19

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

问候克里斯

4

2 回答 2

13

您获得了 __ComObject 类的成员,这是 RCW 的基础 .NET 类。

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

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

于 2012-05-16T11:22:18.050 回答
12

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

在您的示例中,您可以调用DispatchUtility.GetType(comObject, true)以取回一个 .NET 类型实例,然后您可以在该实例上调用 GetProperties 或 GetMembers。

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

于 2013-01-08T03:42:57.533 回答