2009-09-15 21 views
18

Visual StudioでCOMライブラリを参照しているため、対応するInteropアセンブリが自動的に作成されています。これらのcomオブジェクトでGetType()を実行したいと思いますが、それらは常にSystem.__ComObjectを返します。インターフェイスのためにそれらを照会することはいえ作品:COMオブジェクトの種類を取得する方法

bool isOfType = someComeObject is ISomeComObject; //this works 

しかし、私が本当にしたいことは、これは、COMオブジェクトの実際の型を返すことです:

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

誰もが私がやりたい方法を知っています?

答えて

39

はその後Microsoft.VisualBasic.dllへの参照を追加し、:

Microsoft.VisualBasic.Information.TypeName(someCOMObject) 

MSDNのリファレンスhereを。

+0

私はちょうどこれを試して、それは動作します!クラス名だけを返すわけではありませんが、それは私の目的のために大丈夫です。私は内部的に 'LegacyTypeNameOfCOMObject'を呼び出すリフレクターでこのメソッドを見ましたが、実際に何が行われているのか分かりません。 –

+0

私は、衝突を避けるためにcomオブジェクトの完全な名前を与えることができるものがあったと思う。 –

+0

ありがとうございます。これはC#で可能かどうか、任意のアイデアですか? – rpattabi

2

あなたは基本的にそれを理解しました。 COMオブジェクトのGetType()はSystem .__ ComObjectを提供するため、実際にオブジェクトが何であるかを見るためには、別のものにキャストしようとする必要があります。

+0

本当に他の方法はありませんか?既存のすべての可能なCOMオブジェクトをテストすることはできないので、型を欲しいだけです。その理由は、辞書のキーとしてオブジェクトの型を使用しているからです... –

+2

かなり明白です... –

+0

Darin Dimitrovのソリューションは素晴らしいです。 – catfood

0

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

ない最速かつ最もエレガントなソリューション、それが働きました。

+1

'someCOMObject as type'?それがうまくいくかどうかはわかりません。 – nawfal

+0

それはしないので。 – ensisNoctis

1

ダーリンの回答は、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); 
    } 
} 
+0

これはうまくいくようです - 単にITypeInfoの 'System.Runtime.InteropServices.ComTypes'への参照があるようにする必要があります(Visual Studio IDEは自動的に' Microsoft.VisualStudio.OLE.Interop.ITypeInfo'を提案しますが、これはあなたが欲しいものではありません! – ErrCode

関連する問題