2009-09-15 13 views
18

Odwołuję się do biblioteki COM w Visual Studio, więc automatycznie utworzył dla mnie odpowiedni zespół Interop. Chciałbym zrobić GetType() na tych obiektach com, ale zawsze zwracają System.__ComObject. Odpytywanie ich interfejs działa jednak:Jak uzyskać typ obiektu COM

bool isOfType = someComeObject is ISomeComObject; //this works 

Ale to, co naprawdę chcesz jest to, aby powrócić do rzeczywistego typu obiektu COM:

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

czy ktoś wie jak to zrobić, co chcę zrobić ?

Odpowiedz

39

dodawania odniesienia do Microsoft.VisualBasic.dll a następnie:

Microsoft.VisualBasic.Information.TypeName(someCOMObject) 

MSDN odniesienia here.

+0

Po prostu próbowałem tego i działa! Nie zwraca jednak pełnej nazwy, tylko nazwa klasy, ale jest to w porządku dla moich celów. Spojrzałem na tę metodę w odbłyśniku, który wewnętrznie nazywa "LegacyTypeNameOfCOMObject", ale nie wiem, co on właściwie robi. –

+0

Żałuję, że nie było czegoś, co mogłoby dać mi pełną nazwę tego obiektu com, aby uniknąć konfliktów. –

+0

Dzięki. Każdy pomysł, jeśli jest to możliwe w C#? – rpattabi

2

W zasadzie to rozgryzłeś. GetType() na obiekcie COM da ci System .__ ComObject, i musisz spróbować rzucić go na coś innego, aby zobaczyć, czym naprawdę jest obiekt.

+0

Hm ... czy naprawdę nie ma innej drogi? Ponieważ nie mogę przetestować każdego istniejącego obiektu COM, po prostu chcę tego typu. Powodem jest to, że używam typu obiektu jako klucza w słowniku ... –

+2

Dość oczywiste ... –

+0

Rozwiązanie Darina Dimitrova jest wspaniałe. – catfood

0

Natknąłem się na to pytanie kilka dni temu, gdy szukałem pełnej nazwy typu obiektu System.__ComObject. Skończyło się nazwę typu użyciem roztworu Darin a następnie zapętlenie przez wszystkich klas we wszystkich zespołach do testowania mecz:

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

Nie najszybszy i najbardziej eleganckie rozwiązanie, ale to działało.

+1

'someCOMObject as type'? Nie jestem pewien, czy to zadziała. – nawfal

+0

Ponieważ tak nie jest. – ensisNoctis

1

Przyjęta odpowiedź od Darina wymaga zależności od Microsoft.VisualBasic.dll. Jeśli nie chcesz, możesz użyć tej prostej klasy pomocnika:

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

To też wydaje się działać - wystarczy upewnić się, że istnieje odwołanie do 'System.Runtime.InteropServices.ComTypes' dla' ITypeInfo' (Visual Studio IDE automatycznie zasugerowało 'Microsoft.VisualStudio.OLE.Interop.ITypeInfo', ale to to _ ** nie ** _ ten, który chcesz!) – ErrCode

Powiązane problemy