سؤال

وأنا الرجوع إلى مكتبة COM في Visual Studio، لذلك خلقت تلقائيا تجميع إمكانية التشغيل المتداخل المقابلة بالنسبة لي. وأود أن تفعل GetType() على هذه الكائنات كوم، لكنها دائما العودة System.__ComObject. الاستعلام منهم عن واجهة تعمل على الرغم من:

bool isOfType = someComeObject is ISomeComObject; //this works

ولكن ما أريد حقا هو هذا للعودة النوع الفعلي للكائن كوم:

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

لا أحد يعرف كيف أن تفعل ما أريد القيام به؟

هل كانت مفيدة؟

المحلول

إضافة إشارة إلى Microsoft.VisualBasic.dll ثم:

Microsoft.VisualBasic.Information.TypeName(someCOMObject)

هنا .

نصائح أخرى

والجواب مقبولة من قبل دارين يتطلب تبعية إلى 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);
    }
}

ولقد برزت أساسا من ذلك. GetType () على كائن COM هو ذاهب الى ان نعطيكم نظام .__ ComObject، وعليك أن محاولة تحويل إلى شيء آخر لمعرفة ما هو كائن بالفعل.

وأنا تعثرت على هذا السؤال قبل بضعة أيام في حين كنت أبحث عن اسم نوع الكامل للكائن System.__ComObject. انتهى بي الأمر الحصول على اسم نوع باستخدام محلول دارين وثم حلقات من خلال جميع الطبقات في جميع المجالس لاختبار المباراة:

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

وليس الحل الأسرع والأكثر أناقة، لكنه يعمل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top