2012-05-16 126 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