Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get property names via reflection of a COM object

How can I read out all property names via reflection of an COM Object in C#? I know how to get the property if I know the name.

comObject.GetType().InvokeMember("PropertyName", System.Reflection.BindingFlags.GetProperty, null, comObject, null);

but what is when I want to dump all properties?

PropertyInfo[] properties = t.GetProperties();

This way didn't work with Com-Objects. If I do a GetMembers() I get these Members:

Name: GetLifetimeService
Name: InitializeLifetimeService
Name: CreateObjRef
Name: ToString
Name: Equals
Name: GetHashCode
Name: GetType

regards Chris

like image 361
masterchris_99 Avatar asked May 16 '12 08:05

masterchris_99


People also ask

How does reflection set property value?

To set property values via Reflection, you must use the Type. GetProperty() method, then invoke the PropertyInfo. SetValue() method. The default overload that we used accepts the object in which to set the property value, the value itself, and an object array, which in our example is null.

How do I get a property Type from PropertyInfo?

You can do this by getting an array of all properties from the Type. GetProperties method and then iterating the elements in the array, or you can retrieve the PropertyInfo object that represents the property directly by calling the Type. GetProperty method and specifying the property name.

Does GetCustomAttribute use reflection?

Assembly; Console. WriteLine(bookAssembly); The code from earlier that uses Attribute. GetCustomAttribute() is also an example of Reflection.


2 Answers

You got the members of the __ComObject class, the underlying .NET class for an RCW.

COM has a wee bit support for reflection, as long as the COM coclass implements IDispatch, the Automation interface. Not unusual, it is the interface that scripting languages use to make calls. IDispatch.GetIDsOfNames() is always implemented, but you have to know the name of the member up front. IDispatch.GetTypeInfo() gives access to the type library for the coclass, but isn't always implemented. Translation of type library info to metadata is an imperfect art, the core reason why .NET wants you to do this upfront with Tlbimp.exe. If you want to pursue a runtime approach then you'll probably benefit from the source for the managed version of Tlbimp, available here.

Doing this up front at build time is always best, you do so by adding a reference to the type library (usually embedded in the executable file) or by running Tlbimp.exe yourself. Now you got a .NET interop wrapper class that has all of the members of the underlying COM coclass and interfaces. At which point you probably don't need reflection anymore :)

like image 77
Hans Passant Avatar answered Sep 21 '22 22:09

Hans Passant


I've just published a CodeProject article about how to do Reflection with IDispatch-based COM objects. The article provides a small C# DispatchUtility helper class that's easy to include in other projects. Internally, it uses a custom declaration of IDispatch and .NET's TypeToTypeInfoMarshaler to convert IDispatch's ITypeInfo into a rich .NET Type instance.

In your example, you could call DispatchUtility.GetType(comObject, true) to get back a .NET Type instance, which you could then call GetProperties or GetMembers on.

I've also provided a version of the DispatchUtility source code on StackOverflow in a response to How to enumerate members of COM object in C#?

like image 23
Bill Menees Avatar answered Sep 19 '22 22:09

Bill Menees