通过反映COM对象获取属性名称

时间:2012-05-16 08:49:01

标签: c# reflection com properties

如何通过在C#中反映COM对象来读出所有属性名称? 如果我知道这个名字,我知道如何取得房产。

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

但是什么时候我要转储所有属性?

PropertyInfo[] properties = t.GetProperties();

这种方式不适用于Com-Objects。如果我做GetMembers(),我会得到这些成员:

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

问候克里斯

2 个答案:

答案 0 :(得分:12)

您拥有__ComObject类的成员,这是RCW的基础.NET类。

只要COM coclass实现了IDispatch(自动化接口),COM就会对反射提供一点点支持。并不罕见,它是脚本语言用来进行调用的接口。始终实现IDispatch.GetIDsOfNames(),但您必须事先知道该成员的名称。 IDispatch.GetTypeInfo()允许访问coclass的类型库,但并不总是实现。将类型库信息转换为元数据是一种不完美的艺术,这是.NET希望您使用Tlbimp.exe预先执行此操作的核心原因。如果您想采用运行时方法,那么您可能会受益于Tlbimp托管版本的来源available here

在构建时预先执行此操作总是最好的,您可以通过添加对类型库的引用(通常嵌入在可执行文件中)或自行运行Tlbimp.exe来实现。现在你有一个.NET interop包装类,它包含底层COM coclass和接口的所有成员。此时你可能不再需要反思了:)

答案 1 :(得分:11)

我刚刚发布了一篇关于如何Reflection with IDispatch-based COM objects的CodeProject文章。本文提供了一个小的C#DispatchUtility助手类,很容易包含在其他项目中。在内部,它使用IDispatch的自定义声明和.NET的TypeToTypeInfoMarshaler将IDispatch的ITypeInfo转换为丰富的.NET Type实例。

在您的示例中,您可以调用DispatchUtility.GetType(comObject, true)来获取.NET Type实例,然后可以调用GetProperties或GetMembers。

我还在对How to enumerate members of COM object in C#?

的回复中提供了StackOverflow上DispatchUtility源代码的一个版本