Ответ 1
Добавьте ссылку на Microsoft.VisualBasic.dll
, а затем:
Microsoft.VisualBasic.Information.TypeName(someCOMObject)
Ссылка MSDN здесь.
Я ссылаюсь на библиотеку COM в Visual Studio, поэтому он автоматически создал для меня соответствующую сборку Interop. Я хотел бы сделать GetType()
для этих объектов com, но они всегда возвращают System.__ComObject
. Запросить их для интерфейса работает, хотя:
bool isOfType = someComeObject is ISomeComObject; //this works
Но я действительно хочу, чтобы это возвращало фактический тип COM-объекта:
Type type = someComeObject.GetType(); //returns System.__ComObject :-(
Кто-нибудь знает, как делать то, что я хочу сделать?
Добавьте ссылку на Microsoft.VisualBasic.dll
, а затем:
Microsoft.VisualBasic.Information.TypeName(someCOMObject)
Ссылка MSDN здесь.
Вы в основном поняли это. GetType() на COM-объекте даст вам System.__ ComObject, и вы должны попытаться применить его к чему-то еще, чтобы увидеть, что представляет собой объект.
Принятый ответ Дарина требует зависимости от 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.__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;
}
}
Не самое быстрое и элегантное решение, но оно сработало.