.net 如何获取COM对象的类型

.net 如何获取COM对象的类型,.net,reflection,com,interop,com-interop,.net,Reflection,Com,Interop,Com Interop,我正在引用Visual Studio中的COM库,因此它已自动为我创建了相应的互操作程序集。我想对这些com对象执行GetType(),但它们总是返回System.\uu ComObject。但查询它们以获得接口仍然有效: bool isOfType = someComeObject is ISomeComObject; //this works 但我真正想要的是返回com对象的实际类型: Type type = someComeObject.GetType(); //returns Syst

我正在引用Visual Studio中的COM库,因此它已自动为我创建了相应的互操作程序集。我想对这些com对象执行
GetType()
,但它们总是返回
System.\uu ComObject
。但查询它们以获得接口仍然有效:

bool isOfType = someComeObject is ISomeComObject; //this works
但我真正想要的是返回com对象的实际类型:

Type type = someComeObject.GetType(); //returns System.__ComObject :-(

有人知道如何做我想做的事吗?

你基本上已经知道了。COM对象上的GetType()将为您提供System.\u ComObject,您必须尝试将其强制转换为其他对象以查看该对象的真实情况。

添加对Microsoft.VisualBasic.dll的引用,然后:

Microsoft.VisualBasic.Information.TypeName(someCOMObject)

MSDN reference.

几天前,我在查找
系统的完整类型名时偶然发现了这个问题。\uuu 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;
        }
    }

虽然不是最快最优雅的解决方案,但它确实有效。

达林接受的答案要求依赖于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);
    }
}

嗯……真的没有别的办法吗?因为我无法测试现有COM中所有可能的COM对象,所以我只需要类型。原因是我正在使用对象的类型作为字典中的键…Darin Dimitrov的解决方案非常好。我刚刚尝试了这个方法,效果很好!虽然它不返回全名,只返回类名,但这对我来说是可以的。我在reflector中查看了这个方法,它在内部调用“LegacyTypeNameOfMobject”,但我不知道它实际上是做什么的。我希望有什么东西可以给我这个com对象的全名,以避免冲突。
Microsoft.VisualBasic.dll
是一个.NET程序集,可以在每个应用程序中引用和使用。注意如果您有用C++/ATL编写的COM组件,则输出。你可能会得到一个不同于你预期的结果。这正是我想要的。谢谢<代码>某些对象作为类型?不确定这是否可行。因为不行。@nawfal:为什么不行?它试图将“someCOMObject”强制转换为类型“type”。如果失败(并且只有在那时),结果为空。如果没有,则找到了正确的类型。(我知道,我花了几天时间才得出这个答案:-P)@pwhty
type
在你的代码中不是一个类型/类,它是一个类型的实例
作为关键字在类型上起作用这似乎也起作用-只需确保有对
ITypeInfo
System.Runtime.InteropServices.ComTypes
的引用(Visual Studio IDE自动建议
Microsoft.VisualStudio.OLE.Interop.ITypeInfo
,但这不是您想要的!)有没有办法使用它来获取COM对象的库?我有一个Word对象模型中的对象,
TypeName
返回
Shape
,但我无法将其强制转换为
Word.Shape