通过反映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对象的成员?