通过 COM 对象的反射获取属性名称
Posted
技术标签:
【中文标题】通过 COM 对象的反射获取属性名称【英文标题】:Get property names via reflection of a COM object 【发布时间】:2012-05-23 19:23:25 【问题描述】:如何通过 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
问候克里斯
【问题讨论】:
不清楚你在问什么,因为你已经在提供答案了。GetProperties
将返回一个类型的所有属性。
如果 COM 对象实现 IDispatch
,您可以尝试将其转换为 System.Reflection.IReflect
并使用它的方法来检查对象。
【参考方案1】:
您获得了 __ComObject 类的成员,这是 RCW 的基础 .NET 类。
COM 对反射有一点支持,只要 COM coclass 实现 IDispatch,即自动化接口。这并不罕见,它是脚本语言用来进行调用的接口。 IDispatch.GetIDsOfNames() 总是被实现,但你必须事先知道成员的名字。 IDispatch.GetTypeInfo() 允许访问 coclass 的类型库,但并不总是实现。将类型库信息转换为元数据是一门不完美的艺术,这也是 .NET 希望您使用 Tlbimp.exe 预先完成此操作的核心原因。如果您想采用运行时方法,那么您可能会从 Tlbimp 托管版本的源代码available here 中受益。
在构建时预先执行此操作总是最好的,您可以通过添加对类型库的引用(通常嵌入在可执行文件中)或自己运行 Tlbimp.exe 来执行此操作。现在,您获得了一个 .NET 互操作包装类,其中包含底层 COM coclass 和接口的所有成员。到那时你可能不再需要反思了:)
【讨论】:
【参考方案2】:我刚刚发布了一篇关于如何操作Reflection with IDispatch-based COM objects 的 CodeProject 文章。这篇文章提供了一个小的 C# DispatchUtility
帮助类,它很容易包含在其他项目中。在内部,它使用 IDispatch 的自定义声明和 .NET 的 TypeToTypeInfoMarshaler 将 IDispatch 的 ITypeInfo 转换为丰富的 .NET Type 实例。
在您的示例中,您可以调用 DispatchUtility.GetType(comObject, true)
来取回一个 .NET 类型实例,然后您可以在该实例上调用 GetProperties 或 GetMembers。
我还在 *** 上提供了一个版本的 DispatchUtility 源代码,以响应How to enumerate members of COM object in C#?
【讨论】:
感谢您的精彩文章。我尝试使用它,但遇到了问题。我收到错误消息:“类型库是从 clr 程序集中导出的,无法重新导入”我正在使用 Activator.createInstance 创建对象。我为其创建 COM 对象的工具是 Tibco Spotfire v6.5.2,请您帮忙。谢谢 @Bill Menees,你的助手类可以用在PowerShell to create instance of COM object吗?以上是关于通过 COM 对象的反射获取属性名称的主要内容,如果未能解决你的问题,请参考以下文章
项目实战,通过类对象,反射类属性等信息。通过数据库连接信息,获取所有的对象以及结果