2012-05-16 98 views
14

如何通过C#中COM对象的反射读出所有属性名称? 如果我知道名字,我知道如何获得房产。通过反射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

目前尚不清楚你的要求,因为你已经提供了答案。 'GetProperties'将返回一个类型的所有属性。 –

+0

那么'PropertyInfo.Name'? –

+2

但不是COM对象! –

回答

12

你得到了__ComObject类,为RCW基础.NET类的成员。

只要COM coclass实现IDispatch(自动化接口),COM就可以支持反射。并不罕见,它是脚本语言用来进行调用的接口。 IDispatch.GetIDsOfNames()总是实现,但您必须事先知道成员的名称。 IDispatch.GetTypeInfo()允许访问coclass的类型库,但并不总是实现。将类型库信息转换为元数据是一种不完美的艺术,它是.NET要求您使用Tlbimp.exe预先完成的核心原因。如果你想追求运行时方法,那么你可能会从Tlbimp的管理版本available here中受益。

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

10

我刚刚发布了一个CodeProject文章,关于如何做Reflection with IDispatch-based COM objects。本文提供了一个小巧的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#?

+0

谢谢你的精彩文章。我尝试使用它,但面临一个问题。我得到的错误:“类型库是从一个clr程序集导出,不能重新导入” 我正在使用Activator.createInstance来创建对象。我创建COM对象的工具是Tibco Spotfire v6.5.2 请帮忙。谢谢 – Prabhakar

+0

@Bill Menees,你的帮助类可以用在[PowerShell创建COM对象的实例](http://stackoverflow.com/questions/41945859/use-powershell-to-create-instance-of-com-object )? – craig