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

如何通过在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 

对克里斯说

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

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

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

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

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

我还在StackOverflow上提供了一个DispatchUtility源代码版本,以响应如何在C#中枚举COM对象的成员?