如何获取 COM 对象的类型
Posted
技术标签:
【中文标题】如何获取 COM 对象的类型【英文标题】:How to get type of COM object 【发布时间】:2010-11-28 14:38:23 【问题描述】:我在 Visual Studio 中引用了一个 COM 库,因此它已自动为我创建了相应的 Interop 程序集。我想对这些 com 对象执行GetType()
,但它们总是返回System.__ComObject
。不过,查询它们的接口是可行的:
bool isOfType = someComeObject is ISomeComObject; //this works
但我真正想要的是返回 com 对象的实际类型:
Type type = someComeObject.GetType(); //returns System.__ComObject :-(
有人知道我想做的事怎么做吗?
【问题讨论】:
【参考方案1】:添加对Microsoft.VisualBasic.dll
的引用,然后:
Microsoft.VisualBasic.Information.TypeName(someCOMObject)
MSDN 参考here。
【讨论】:
我刚试过这个,它有效!虽然它不返回全名,只返回类名,但这对于我的目的来说是可以的。我在内部调用“LegacyTypeNameOfCOMObject”的反射器中查看了这个方法,但我不知道它实际上做了什么。 我希望有什么东西可以给我该 com 对象的全名以避免冲突。Microsoft.VisualBasic.dll
是一个 .NET 程序集,可以在每个应用程序中引用和使用。
注意您是否有用 C++/ATL 编写的 COM 组件。您可能会得到与预期不同的结果。
正是我想要的。谢谢!【参考方案2】:
Darin 接受的答案需要依赖于 Microsoft.VisualBasic.dll
。如果你不想这样,你可以使用这个简单的帮助类:
public static class TypeInformation
public static string GetTypeName(object comObject)
var dispatch = comObject as IDispatch;
if (dispatch == null)
return null;
var pTypeInfo = dispatch.GetTypeInfo(0, 1033);
string pBstrName;
string pBstrDocString;
int pdwHelpContext;
string pBstrHelpFile;
pTypeInfo.GetDocumentation(
-1,
out pBstrName,
out pBstrDocString,
out pdwHelpContext,
out pBstrHelpFile);
string str = pBstrName;
if (str[0] == 95)
// remove leading '_'
str = str.Substring(1);
return str;
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("00020400-0000-0000-C000-000000000046")]
private interface IDispatch
int GetTypeInfoCount();
[return: MarshalAs(UnmanagedType.Interface)]
ITypeInfo GetTypeInfo(
[In, MarshalAs(UnmanagedType.U4)] int iTInfo,
[In, MarshalAs(UnmanagedType.U4)] int lcid);
void GetIDsOfNames(
[In] ref Guid riid,
[In, MarshalAs(UnmanagedType.LPArray)] string[] rgszNames,
[In, MarshalAs(UnmanagedType.U4)] int cNames,
[In, MarshalAs(UnmanagedType.U4)] int lcid,
[Out, MarshalAs(UnmanagedType.LPArray)] int[] rgDispId);
【讨论】:
这似乎也有效 - 只需要确保System.Runtime.InteropServices.ComTypes
引用 ITypeInfo
(Visual Studio IDE 自动建议 Microsoft.VisualStudio.OLE.Interop.ITypeInfo
,但这是 不是你想要的!)
有什么办法可以用这个来获取COM对象的库吗?我有一个来自 Word 对象模型的对象,TypeName
为其返回 Shape
,但我无法将其转换为 Word.Shape
source in VBA。【参考方案3】:
你基本上已经明白了。 COM 对象上的 GetType() 将为您提供 System.__ComObject,您必须尝试将其强制转换为其他对象才能查看该对象的真正含义。
【讨论】:
嗯..真的没有别的办法了吗?因为我无法测试现有的每个可能的 COM 对象,所以我只想要类型。原因是我使用对象的类型作为字典中的键... Darin Dimitrov 的解决方案很棒。【参考方案4】:几天前我在寻找System.__ComObject
对象的完整类型名称时偶然发现了这个问题。我最终使用 Darin 的解决方案获得了类型名称,然后遍历所有程序集中的所有类以测试匹配:
typeName = Microsoft.VisualBasic.Information.TypeName(someCOMObject);
foreach (System.Reflection.Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
foreach (Type type in assembly.GetTypes())
if ((someCOMObject as type)!=null)
fullTypeName = type.FullName;
不是最快和最优雅的解决方案,但它确实有效。
【讨论】:
someCOMObject as type
?不确定这是否可行。
因为没有。
@nawfal:为什么不呢?它试图将“someCOMObject”转换为“type”类型。如果它失败(并且只有那时),则结果为空。如果没有,那么它找到了正确的类型。 (我知道,我花了几天时间才得出这个答案:-P)
@pwhty type
不是代码中的类型/类,它是类型的实例。 as
关键字适用于 type以上是关于如何获取 COM 对象的类型的主要内容,如果未能解决你的问题,请参考以下文章