31

我在 Visual Studio 中引用了一个 COM 库,因此它自动为我创建了相应的互操作程序集。我想GetType()对这些 com 对象做一个,但它们总是返回System.__ComObject. 不过,查询它们的接口是可行的:

bool isOfType = someComeObject is ISomeComObject; //this works

但我真正想要的是返回 com 对象的实际类型:

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

有谁知道如何做我想做的事?

4

4 回答 4

60

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

Microsoft.VisualBasic.Information.TypeName(someCOMObject)

MSDN 参考这里

于 2009-09-15T20:56:38.113 回答
13

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);
    }
}
于 2017-09-08T07:44:46.313 回答
2

你基本上已经想通了。COM 对象上的 GetType() 将为您提供 System.__ComObject,您必须尝试将其强制转换为其他对象才能查看该对象的真正含义。

于 2009-09-15T20:54:52.220 回答
-2

几天前,我在寻找对象的完整类型名称时偶然发现了这个问题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;
        }
    }

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

于 2013-09-28T14:33:42.337 回答