Pregunta

Estoy haciendo referencia a una biblioteca COM en Visual Studio, por lo que ha creado automáticamente el ensamblado de interoperabilidad correspondiente para mí. Me gustaría hacer un GetType () en estos objetos com, pero siempre devuelven System .__ ComObject . Sin embargo, consultarlos para obtener una interfaz funciona:

bool isOfType = someComeObject is ISomeComObject; //this works

Pero lo que realmente quiero es que devuelva el tipo real del objeto com:

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

¿Alguien sabe cómo hacer lo que quiero hacer?

¿Fue útil?

Solución

Agregue referencia a Microsoft.VisualBasic.dll y luego:

Microsoft.VisualBasic.Information.TypeName(someCOMObject)

Referencia de MSDN aquí .

Otros consejos

La respuesta aceptada por Darin requiere una dependencia de Microsoft.VisualBasic.dll . Si no quiere tener eso, puede usar esta simple clase auxiliar:

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);
    }
}

Básicamente lo has descubierto. GetType () en un objeto COM le dará Sistema .__ ComObject, y debe intentar convertirlo en otra cosa para ver cuál es realmente el objeto.

Me topé con esta pregunta hace unos días mientras buscaba el nombre de tipo completo de un objeto System .__ ComObject . Terminé obteniendo el nombre del tipo usando la solución de Darin y luego recorriendo todas las clases en todos los ensamblajes para probar la coincidencia:

    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;
        }
    }

No es la solución más rápida y elegante, pero funcionó.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top