Word automation and late/early binding

M

Mystery Man

We are developing a C# application that has many interfaces to the
Microsoft suite (eg Word, Excel, Outlook, Powerpoint, etc). We need to
support Office 97, 2000, 2002 and any future versions.

Our first cut used early binding and worked fine with Office 2002. We
then ran on a machine that had Office 2000 installed and it all turned
to custard.

There appears to be a number of options to take to support multiple
versions:

(1) Use early binding on the lowest common demoninator (in our case
office 97)
(2) Use early binding for each office version (ie in our case, have
three different assemblies for 97, 2000 and 2002)
(3) Use late binding

We would prefer to go with Option (1) as this means no code changes
(not yet clarified). However, we are not convinced that this is the
correct thing to do.

What do others think?
 
N

Nicholas Paldino [.NET/C# MVP]

Mystery Man,

Technically, you should be able to go with option #1, as COM interfaces
are supposed to be immutable. However, the implementations behind each may
have changed. If you are not making that many calls to Office, then you
might want to consider #3, because you could do it all in code without any
interop assemblies.

Avoid #2 at all costs. That is just a nightmare waiting to happen.

Hope this helps.
 
M

Michael R

I have successfully used the sample code below to control Word 2K and XP.
This was an Extensibility project so the app was started when Word started
but you should be able to use late binding on the generic "Word.Application"
to do the same thing. The project used the Primary Interop Assemblies for
XP but they were not "installed". The required interop assemblies were
placed in the same directory as the project dll.

Specific method calls require checking the version you are running on. I
used only Open and SaveAs but others include Compare, Merge, Sort and
PrintOut.

Hope this helps.

//get the version of Word we are running
WordVersion = (string)appObj.GetType().InvokeMember("Version",
BindingFlags.GetProperty , null, appObj , 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 == OfficeXP ) // OfficeXP is a constant defined as 10.0
{
// the Word XP version 10.0 events
oType = typeof(Word.ApplicationEvents3_Event);

//DocumentOpen
oEvent = oType.GetEvent("DocumentOpen", oBindFlags);
oMethod = oEvent.GetAddMethod();
result = oMethod.Invoke(appObj, new object [] { new
Word.ApplicationEvents3_DocumentOpenEventHandler(this.DocOpenEventHandler) }
);
}
else if ( WordVersion == Office2K )
{
// The Word 2000 version 9.0 events
oType = typeof(Word.ApplicationEvents2_Event);

//DocumentOpen
oEvent = oType.GetEvent("DocumentOpen", oBindFlags);
oMethod = oEvent.GetAddMethod();
result = oMethod.Invoke(appObj, new object [] { new
Word.ApplicationEvents2_DocumentOpenEventHandler(this.DocOpenEventHandler) }
);
}



if ( WordVersion == OfficeXP )
appObj.Documents.Open(ref sFile, ref No, ref No, ref No, ref oMissing, ref
oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref
oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
else if ( WordVersion == Office2K )
appObj.Documents.Open2000(ref sFile, ref No, ref No, ref No, ref oMissing,
ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref
oMissing, ref oMissing);
else if ( WordVersion == ? )
appObj.Documents.OpenOld(...); // I assume this will open a Word97
document??
else
throw new Exception("Unknown Word Version");


--
Michael R
(e-mail address removed)



Nicholas Paldino said:
Mystery Man,

Technically, you should be able to go with option #1, as COM interfaces
are supposed to be immutable. However, the implementations behind each may
have changed. If you are not making that many calls to Office, then you
might want to consider #3, because you could do it all in code without any
interop assemblies.

Avoid #2 at all costs. That is just a nightmare waiting to happen.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Mystery Man said:
We are developing a C# application that has many interfaces to the
Microsoft suite (eg Word, Excel, Outlook, Powerpoint, etc). We need to
support Office 97, 2000, 2002 and any future versions.

Our first cut used early binding and worked fine with Office 2002. We
then ran on a machine that had Office 2000 installed and it all turned
to custard.

There appears to be a number of options to take to support multiple
versions:

(1) Use early binding on the lowest common demoninator (in our case
office 97)
(2) Use early binding for each office version (ie in our case, have
three different assemblies for 97, 2000 and 2002)
(3) Use late binding

We would prefer to go with Option (1) as this means no code changes
(not yet clarified). However, we are not convinced that this is the
correct thing to do.

What do others think?
 

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