Is reflection really necessary when using the PIAs from another application?

D

DarrylR

I have discovered (much to my disappointment) that in order to access Word
document properties and methods from a Windows Forms application, I have to
use reflection instead of calling the methods directly. For example, when I
need to access the Word.Document.CustomDocumentProperties collection from
VSTO (VBA would be similar), I can use the following syntax:

Microsoft.Office.Interop.Word.ApplicationClass objWdClass =
new Microsoft.Office.Interop.Word.ApplicationClass();
Microsoft.Office.Interop.Word.Document objDoc =
objWdClass.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref
oMissing);
string strPropertyName = "ProductId";
object objValue = "theproductid";
Microsoft.Office.Core.DocumentProperties objDocProps =
(Microsoft.Office.Core.DocumentProperties)objDoc.CustomDocumentProperties;
objDocProps[strPropertyName].Value = objValue;

However, the aforementioned code throws a 'cast is invalid' exception when
you attempt to cast the object returned by objDoc.CustomDocumentProperties
to type DocumentProperties. As a result, I was forced to use the following
syntax:

object oDocCustomProps = objDoc.CustomDocumentProperties;
Type typeDocCustomProps = oDocCustomProps.GetType();
object oCustomProp = typeDocCustomProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.GetProperty,
null, oDocCustomProps,
new object[] {strPropertyName});

typeDocCustomProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.SetProperty,
null, oDocCustomProps,
new object[] {strPropertyName, objValue} );

I realize that the objects need to be marshalled across processes. But is it
really necessary to use reflection? Is there anything that would make this
easier? Any information/advice would be greatly appreciated.

Thanks,
Darryl R.
 
C

Cindy M -WordMVP-

Hi DarrylR,

You only need to use late-binding (what you're calling reflection) for things
that are late bound the object library you're working with. In the case of
Word, the custom document properties are late-bound into Word, so you can't
access them directly through the object model. The same goes for WordBasic
commands and the Word dialog box arguments.

Visual Basic can do this, if Option Strict is not on.

If you don't want to go the long route, then you could create a VB project
class with Option Strict off and import that into your C# project. Then use
the methods in the VB project to work with the custom document properties.

Other than that, you can set up a "library" of methods so that you don't have
to rewrite the reflection code every time you want to access them.
I have discovered (much to my disappointment) that in order to access Word
document properties and methods from a Windows Forms application, I have to
use reflection instead of calling the methods directly. For example, when I
need to access the Word.Document.CustomDocumentProperties collection from
VSTO (VBA would be similar), I can use the following syntax:

Microsoft.Office.Interop.Word.ApplicationClass objWdClass =
new Microsoft.Office.Interop.Word.ApplicationClass();
Microsoft.Office.Interop.Word.Document objDoc =
objWdClass.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref
oMissing);
string strPropertyName = "ProductId";
object objValue = "theproductid";
Microsoft.Office.Core.DocumentProperties objDocProps =
(Microsoft.Office.Core.DocumentProperties)objDoc.CustomDocumentProperties;
objDocProps[strPropertyName].Value = objValue;

However, the aforementioned code throws a 'cast is invalid' exception when
you attempt to cast the object returned by objDoc.CustomDocumentProperties
to type DocumentProperties. As a result, I was forced to use the following
syntax:

object oDocCustomProps = objDoc.CustomDocumentProperties;
Type typeDocCustomProps = oDocCustomProps.GetType();
object oCustomProp = typeDocCustomProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.GetProperty,
null, oDocCustomProps,
new object[] {strPropertyName});

typeDocCustomProps.InvokeMember("Item",
BindingFlags.Default |
BindingFlags.SetProperty,
null, oDocCustomProps,
new object[] {strPropertyName, objValue} );

I realize that the objects need to be marshalled across processes. But is it
really necessary to use reflection? Is there anything that would make this
easier? Any information/advice would be greatly appreciated.

Cindy Meister
INTER-Solutions, Switzerland
http://homepage.swissonline.ch/cindymeister (last update Jun 8 2004)
http://www.word.mvps.org

This reply is posted in the Newsgroup; please post any follow question or
reply in the newsgroup and not by e-mail :)
 
M

Michael Herzfeld [MSFT]

Hi Darryl. According to our developers, this is a problem with the way
these types were originally defined (many years ago), and we can't fix
it without breaking compatibility, so unfortunately, if you're
programming in C# you'll need to use reflection.

Michael Herzfeld
Office Programmability Test Team


-----Original Message-----
From: DarrylR [mailto:[email protected]]
Posted At: Wednesday, December 21, 2005 10:04 AM
Posted To: microsoft.public.office.developer.automation
Conversation: Is reflection really necessary when using the PIAs from
another application?
Subject: Re: Is reflection really necessary when using the PIAs from
another application?

Thanks, Cindy! -DKR
 
Top