(.NET / C#) Word automation HELP! (Is MS Outlook a bad citizen?)

D

ditt

I have been using Word Automation to make use of Word's spell checking
capabilities. Everything works really well with a couple of exceptions
stemming from how other apps (like Outlook!) insist on using MY
automated instance of Word. Here's the scenario:

I create an instance of word as follows:
======================= C# ===========================
//
// See knowledge base article :
// http://support.microsoft.com/?kbid=188546
// for why we do this double application creation nonsense...
//
Microsoft.Office.Interop.Word.Application tempApp =
new Microsoft.Office.Interop.Word.Application();

tempApp.DisplayAlerts =
Microsoft.Office.Interop.Word.WdAlertLevel.wdAlertsNone;
tempApp.Visible = false;

WordSpellCheck.wordApp =
new Microsoft.Office.Interop.Word.Application();
wordApp.Visible = false;
wordApp.DisplayAlerts =
Microsoft.Office.Interop.Word.WdAlertLevel.wdAlertsNone;

tempApp.Quit(ref WordSpellCheck.missing,
ref rdSpellCheck.missing, ref WordSpellCheck.missing);
tempApp = null;
==========================================================

This will create a hidden Word application instance. According to the
knowledge-base article referenced in the comment above, other
applications should NOT be using my instance of Word and the article
gives a workaround to prevent this behavior. That said, Outlook (2000,
2002, and 2003) continues to insist on using the Word Application which
I started for it's own purposes. For example, if the user has Oulook
setup to use Word at its editor
-OR-
the user clicks on a Word attachment in an email, a new instance of
Word will NOT be generated, rather, it uses my instance.

I really wouldn't have a problem with this behavior, however there are
two really bad side-effects. First, if I create the instance, I should
be able to shut it down. However if Outlook has attached to it, I
cannot. To get around this I check to make sure that the UserControl
property of the WordApplication instance is false and if NOT false I do
NOT call Quit on the instance. This prevents me from killing a Word
document that a user is viewing. However, Outlook will not shut down
this instance of Word when it shuts down either, leaving an orphan Word
Application process running. I am very careful to set all of my
references to the Word Application and any Word Documents and
interfaces to null when my application quits, so I don't know what else
I can do. My feeling is that Outlook simply will NOT shut down the
Word instance if it did not start it.

Second, when my application is running with Office 2000, or 2002, and
Outlook tries to open a Word document using an instance of Word that I
created for automation, it seems to completely ignore the fact that my
instance of Word is hidden. The result is that the document window
appears way off the top-left corner of the screen; you can only see the
sizing grab lines of the lower right corner of the document window.
This is clearly wrong. Word or Outlook 2003 seems to handle this
situation reasonably well by centering the document window.

Further testing shows me that if in addition to setting my Word
Application instance to hidden (i.e. Visible = false), I also set the
ScreenUpdating property of the Word Application to false, the document
windows opened by Outlook are unusable (i.e. no screen updating
happens). I do not require ScreenUpdating since my document, only used
for spell checking, is never seen by the user.

I can understand if someone were to say that when you start an instance
of Word you cannot guarantee that only your thread/application will
access it, however if some other application is going to attach and use
your instance of Word, isn't it or shouldn't it be the responsibility
of THAT application to make sure the instance their attaching to is
capable of performing the forthcoming operations/actions? Outlook
seems to be completely blind to the capabilities of the Word
application it uses and simply hopes for the best.

So, this leaves me thinking that I have two choices:

1) Find a way to prevent other applications (like Outlook!) from
attaching to my instance of Word.

2) Chalk the current behavior up to a blatant BUG in Outlook and
document the behavior for my users.

I'm hoping that someone in this group can offer some assistance or
pointers.

Thanks in advance,

ditt7
 
D

ditt

ditt said:
I have been using Word Automation to make use of Word's spell checking
capabilities. Everything works really well with a couple of exceptions
stemming from how other apps (like Outlook!) insist on using MY
automated instance of Word. Here's the scenario:

I create an instance of word as follows:
======================= C# ===========================
//
// See knowledge base article :
// http://support.microsoft.com/?kbid=188546
// for why we do this double application creation nonsense...
//
Microsoft.Office.Interop.Word.Application tempApp =
new Microsoft.Office.Interop.Word.Application();

tempApp.DisplayAlerts =
Microsoft.Office.Interop.Word.WdAlertLevel.wdAlertsNone;
tempApp.Visible = false;

WordSpellCheck.wordApp =
new Microsoft.Office.Interop.Word.Application();
wordApp.Visible = false;
wordApp.DisplayAlerts =
Microsoft.Office.Interop.Word.WdAlertLevel.wdAlertsNone;

tempApp.Quit(ref WordSpellCheck.missing,
ref rdSpellCheck.missing, ref WordSpellCheck.missing);
tempApp = null;
==========================================================

This will create a hidden Word application instance. According to the
knowledge-base article referenced in the comment above, other
applications should NOT be using my instance of Word and the article
gives a workaround to prevent this behavior. That said, Outlook (2000,
2002, and 2003) continues to insist on using the Word Application which
I started for it's own purposes. For example, if the user has Oulook
setup to use Word at its editor
-OR-
the user clicks on a Word attachment in an email, a new instance of
Word will NOT be generated, rather, it uses my instance.

I really wouldn't have a problem with this behavior, however there are
two really bad side-effects. First, if I create the instance, I should
be able to shut it down. However if Outlook has attached to it, I
cannot. To get around this I check to make sure that the UserControl
property of the WordApplication instance is false and if NOT false I do
NOT call Quit on the instance. This prevents me from killing a Word
document that a user is viewing. However, Outlook will not shut down
this instance of Word when it shuts down either, leaving an orphan Word
Application process running. I am very careful to set all of my
references to the Word Application and any Word Documents and
interfaces to null when my application quits, so I don't know what else
I can do. My feeling is that Outlook simply will NOT shut down the
Word instance if it did not start it.

Second, when my application is running with Office 2000, or 2002, and
Outlook tries to open a Word document using an instance of Word that I
created for automation, it seems to completely ignore the fact that my
instance of Word is hidden. The result is that the document window
appears way off the top-left corner of the screen; you can only see the
sizing grab lines of the lower right corner of the document window.
This is clearly wrong. Word or Outlook 2003 seems to handle this
situation reasonably well by centering the document window.

Further testing shows me that if in addition to setting my Word
Application instance to hidden (i.e. Visible = false), I also set the
ScreenUpdating property of the Word Application to false, the document
windows opened by Outlook are unusable (i.e. no screen updating
happens). I do not require ScreenUpdating since my document, only used
for spell checking, is never seen by the user.

I can understand if someone were to say that when you start an instance
of Word you cannot guarantee that only your thread/application will
access it, however if some other application is going to attach and use
your instance of Word, isn't it or shouldn't it be the responsibility
of THAT application to make sure the instance their attaching to is
capable of performing the forthcoming operations/actions? Outlook
seems to be completely blind to the capabilities of the Word
application it uses and simply hopes for the best.

So, this leaves me thinking that I have two choices:

1) Find a way to prevent other applications (like Outlook!) from
attaching to my instance of Word.

2) Chalk the current behavior up to a blatant BUG in Outlook and
document the behavior for my users.

I'm hoping that someone in this group can offer some assistance or
pointers.

Thanks in advance,

ditt7

Here's an update for anyone trying to deal with this same or similar
issue. My head was sufficiently bludgened from beating it against a
wall, and since I haven't recieved any help from the news groups
(yet...) and I'm not one to simply give up and document poor
functionality I took matters into my own hands. I have successfully
used late binding to register event handlers for the WindowActivate
event with my instance of the Word Application (thanks to another
poster for the roadmap!):

================================C#===============================
string wordVersion =
(string)myWordApp.GetType().InvokeMember("Version",
BindingFlags.GetProperty , null, myWordApp, null);

//add event handlers via reflection
BindingFlags oBindFlags = (BindingFlags.Instance | BindingFlags.Public
| BindingFlags.NonPublic);
Type oType;
EventInfo oEvent;
MethodInfo oMethod;
object result;

// add our handlers to the events based on app
if(wordVersion == Office3K){
// the Word 3K version 11.0 events
oType =
typeof(Microsoft.Office.Interop.Word.ApplicationEvents4_Event);
//WindowActivate
oEvent = oType.GetEvent("WindowActivate", oBindFlags);
oMethod = oEvent.GetRemoveMethod();
result = oMethod.Invoke(appObj, new object [] { new
Microsoft.Office.Interop.Word.ApplicationEvents4_WindowActivateEventHandler(WindowActivateEventHandler)});

}else if(wordVersion == OfficeXP){
// the Word XP version 10.0 events
oType =
typeof(Microsoft.Office.Interop.Word.ApplicationEvents3_Event);
//WindowActivate
oEvent = oType.GetEvent("WindowActivate", oBindFlags);
oMethod = oEvent.GetRemoveMethod();
result = oMethod.Invoke(appObj, new object [] { new
Microsoft.Office.Interop.Word.ApplicationEvents3_WindowActivateEventHandler(WindowActivateEventHandler)});


}else if(wordVersion == Office2K){
// The Word 2000 version 9.0 events
oType =
typeof(Microsoft.Office.Interop.Word.ApplicationEvents2_Event);
//WindowActivate
oEvent = oType.GetEvent("WindowActivate", oBindFlags);
oMethod = oEvent.GetRemoveMethod();
result = oMethod.Invoke(appObj, new object [] { new
Microsoft.Office.Interop.Word.ApplicationEvents2_WindowActivateEventHandler(WindowActivateEventHandler)});

}
=============================================================

Note that the constants Office2K="9.0" OfficeXP="10.0" and
Office3K="11.0".

In my event handler I check for windows that are off the top left of
the screen with little or no visible usable area and move the top,left
to 0,0 when they are activated. It's not the most elegant fix, but
since I know that MY document, which is not visible, should never
generate this event, the event will come from some other app creating
and displaying a document using MY instance of word. This trick, at
least makes things behave in a reasonable fashion. It would be nice if
the creators of Outlook (are you listening Microsoft?) made the
application behave in a reasonable fashion.

FYI, I first tried to use the DocumentOpen event, but *for SOME reason*
when Outlook is set to use Word as it's email editor, this type of
document doesn't generate the DocumentOpen event (Napolean says "Ugh!,
God!) which just seems wrong. This resulted in new mail messages
showing up off the top left corner of the screen when Outlook used my
hidden Word Application instance. It just keeps gettin' better.

I still cannot address the issue of a possible orphan Word process when
Outlook latches on to my instance, but this *should* be a rare case.

I'm still hoping for a more elegant solution to the overall issue from
somebody with more COM/Automation experience than I have. Someone from
MS who can explain Outlook's behavior would be a welcomed bonus.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top