2009-09-15 38 views
18

Tôi đang tham khảo thư viện COM trong Visual Studio, vì vậy nó đã tự động tạo ra lắp ráp Interop tương ứng đối với tôi. Tôi muốn thực hiện một số GetType() trên các đối tượng com này, nhưng chúng luôn trả lại System.__ComObject. Truy vấn họ cho một giao diện làm việc mặc dù:Làm thế nào để có được loại đối tượng COM

bool isOfType = someComeObject is ISomeComObject; //this works 

Nhưng những gì tôi thực sự muốn là ước muốn được trở loại thực tế của đối tượng com:

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

Có ai biết làm thế nào để làm những gì tôi muốn làm ?

Trả lời

39

Thêm tham chiếu đến Microsoft.VisualBasic.dll và sau đó:

Microsoft.VisualBasic.Information.TypeName(someCOMObject) 

MSDN tham khảo here.

+0

Tôi vừa thử cái này và nó hoạt động! Nó không trả lại tên đầy đủ mặc dù, chỉ là tên lớp, nhưng đó là ok cho các mục đích của tôi. Tôi nhìn vào phương pháp này trong phản xạ mà nội bộ gọi là 'LegacyTypeNameOfCOMObject' nhưng tôi không thể tìm ra những gì nó thực sự làm. –

+0

Tôi ước gì có cái gì đó có thể cho tôi tên đầy đủ của vật thể đó để tránh đụng độ. –

+0

Cảm ơn. Bất kỳ ý tưởng nếu điều này là có thể trong C#? – rpattabi

2

Bạn đã tìm hiểu về cơ bản. GetType() trên một đối tượng COM sẽ cung cấp cho bạn System .__ ComObject, và bạn phải thử truyền nó đến một cái gì đó khác để xem đối tượng thực sự là gì.

+0

Hm..không có cách nào khác? Bởi vì tôi không thể kiểm tra cho mọi đối tượng COM có thể tồn tại, tôi chỉ muốn loại đó. Lý do là tôi đang sử dụng loại đối tượng làm khóa trong từ điển ... –

+2

Khá rõ ràng ... –

+0

Giải pháp của Darin Dimitrov rất tuyệt. – catfood

0

tôi stumbled khi câu hỏi này cách đây vài ngày trong khi tôi đang tìm kiếm các loại tên đầy đủ của một đối tượng System.__ComObject. Tôi đã nhận được tên loại bằng cách sử dụng giải pháp của Darin và sau đó lặp qua tất cả các lớp trong tất cả các hội đồng để kiểm tra trận đấu:

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

Không phải là giải pháp nhanh nhất và thanh lịch nhất.

+1

'someCOMObject là kiểu'? Không chắc chắn nếu điều đó sẽ làm việc. – nawfal

+0

Vì không. – ensisNoctis

1

Câu trả lời được chấp nhận bởi Darin đòi hỏi một sự phụ thuộc vào Microsoft.VisualBasic.dll. Nếu bạn không muốn có, bạn có thể sử dụng lớp trợ giúp đơn giản này:

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

Điều này dường như cũng hoạt động - chỉ cần đảm bảo có tham chiếu đến 'System.Runtime.InteropServices.ComTypes' cho' ITypeInfo' (Visual Studio IDE tự động đề xuất 'Microsoft.VisualStudio.OLE.Interop.ITypeInfo', nhưng điều này là _ ** không ** _ cái bạn muốn!) – ErrCode

Các vấn đề liên quan