トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

Visual Studio .NET 2003 C#、COMオブジェクトの種類を得る。

[カテゴリ:言語]
[カテゴリ:C#]

Visual Studio .NET 2003 C#、COMオブジェクトの種類を得る。20080129

たとえば、ExcelのCOMで戻り値がobject型のとき、何が入っているのか種類を調べたいことがある。

.Netの普通のオブジェクトなら、

obj.GetType().FullName

でわかるが、COMオブジェクトを格納したobjectの場合、
"System.__ComObject" しか返ってこないので意味をなさない。

ここでは3つの方法をあげる。

ちなみに、独自に行っている方法3は
.NET2005以降はもうちょっとシンプルにできるのかもしれない。

方法1、asで見る。

HOW TO:Visual C# .NET の COM オブジェクト(System.ComObject)の種類を確認します。
http://support.microsoft.com/default.aspx?scid=kb;ja;320523

デメリット
正体不明のCOMオブジェクトには使えない。

方法2、VBのTypeName()を呼ぶ。

C:\WINNT\Microsoft.NET\Framework\v1.1.xxxx\Microsoft.VisualBasic.dll
を参照すれば C#からでも呼べる。

Microsoft.VisualBasic.Information.TypeName()

デメリット
そのままの名称を返すのではなく、ちょこっと編集されて返してくることがある。
たとえば、Excel.Application のとき、ApplicationClass になったりする。

方法3、独自関数

逆コンパイルでVBのTypeNameが何をやってるのか調べてみると、
わりと簡単に抜き出せそうだったので、独自に作ってみた。

判断ロジックは、IDispatch、IProvideClassInfo の2ルートがあるが
ExcelのApplicationやRangeなどはIDispatchルートだったので
IProvideClassInfoは未確認。

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("B196B283-BAB4-101A-B69C-00AA00341D07")]
    public interface IProvideClassInfo
{
    [return: MarshalAs(UnmanagedType.Interface)]
    UCOMITypeInfo GetClassInfo();
}

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")]
    public interface IDispatch
{
    [PreserveSig]
    int GetTypeInfoCount();
    [PreserveSig]
    int GetTypeInfo([In] int index, [In] int lcid, [MarshalAs(UnmanagedType.Interface)] out UCOMITypeInfo pTypeInfo);
    [PreserveSig]
    int GetIDsOfNames();
    [PreserveSig]
    int Invoke();
}

public static string GetComClassName(object comobj_)
{
    if (Marshal.IsComObject(comobj_) == false)
    {
        return null;
    }

    UCOMITypeInfo typeinfo = null;
    if (typeinfo == null && comobj_ is IDispatch)
    {
        IDispatch dispatch = (IDispatch)comobj_;
        dispatch.GetTypeInfo(0, 0x409, out typeinfo);
    }
    if (typeinfo == null && comobj_ is IProvideClassInfo)
    {
        IProvideClassInfo provideclassinfo = (IProvideClassInfo)comobj_;
        typeinfo = provideclassinfo.GetClassInfo();
    }
    if (typeinfo != null)
    {
        string strName;
        string strDocString;
        int dwHelpContext;
        string strHelpFile;
        typeinfo.GetDocumentation(-1, out strName, out strDocString, out dwHelpContext, out strHelpFile);
        return strName;
    }
    return null;
}

Microsoftのドキュメントできてた。20090208

Visual Basic: リフレクションを使用して COM オブジェクトを検査する
http://msdn.microsoft.com/ja-jp/magazine/2009.01.basicinstincts.aspx

Microsoftがurl変更してた。20090920

Visual Basic: リフレクションを使用して COM オブジェクトを検査する
http://msdn.microsoft.com/ja-jp/magazine/dd347981.aspx

最終更新時間:2009年09月20日 22時18分07秒