.NET言語でクラスID (CLSID) からオブジェクトを作成する方法として、Marshal.BindToMonikerを使う話をします。

よく、Type.GetTypeFromCLSID→Activator.CreateInstanceの組み合わせを見かけます(例:プラットフォーム呼び出し (C# によるプログラミング入門)など)。しかし、Marshal.BindToMonikerとnewモニカの組み合わせでも実現できることを最近知りました。しかもこのほうがより簡単であることは、あまり知られていないように感じます。

紹介・比較

まずは、コードを見てみましょう。Marshal.BindToMonikerとnewモニカを使うと、たった1メソッド呼び出しでCOMオブジェクトを作成できます。

dynamic doc2 = Marshal.BindToMoniker(
  "new:88D96A05-F192-11D4-A65F-0040963251E5");

一方、従来よく見かけるType.GetTypeFromCLSIDとActivator.CreateInstanceによる方法です。まずTypeオブジェクトを作り、それから実体作成という2つの手順が必要です。

var t = Type.GetTypeFromCLSID(
  new Guid("88D96A05-F192-11D4-A65F-0040963251E5"));
dynamic doc = Activator.CreateInstance(t);

Marshal.BindToMonikerとnewモニカは、それぞれ以下のような代物です。

  • Marshal.BindToMonikerはモニカの文字列表現からCOMオブジェクトを取得するメソッドです。
  • newモニカ(の文字列表現)とは、new:に続けてクラスIDを書いたものです。このモニカは、クラスIDのオブジェクトを作る効果があります。なお、{}で囲った"new:{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"の形式でも大丈夫です。

欠点

1つ難点があるとすれば、公式の情報が乏しいことです。newモニカ自体の説明はOLE Moniker Implementationsに存在せず、The COM Elevation Monikerの一部として紹介されているのみです。

とくに、いつのWindowsから使えるか分かる資料のないことが若干不安です。MSDNライブラリの記載から言えることとして、COM Elevation Monikerの登場したWindows Vista以上で使用できることは確実です。一方で、Windows XPでも使用できることは、実際に動かして確かめました。

Appendix: コード例全体

余談ですが、コード例に使用したクラスID {88D96A05-F192-11D4-A65F-0040963251E5}は、MSXML 6.0のDOMドキュメント (ProgID: Msxml2.DOMDocument.6.0) のことです。参照: MSXML 6.0 GUIDs and ProgIDs

using System;
using System.Runtime.InteropServices;
 
class Program
{
  static void Main()
  {
    var t = Type.GetTypeFromCLSID(
      new Guid("88D96A05-F192-11D4-A65F-0040963251E5"));
    dynamic doc = Activator.CreateInstance(t);
 
    doc.loadXML("<hoge>piyo1</hoge>");
    dynamic node1 = doc.selectSingleNode("//hoge");
    Console.WriteLine(node1.text);
 
    dynamic doc2 = Marshal.BindToMoniker(
      "new:88D96A05-F192-11D4-A65F-0040963251E5");
 
    doc2.loadXML("<hoge>piyo2</hoge>");
    dynamic node2 = doc2.selectSingleNode("//hoge");
    Console.WriteLine(node2.text);
  }
}

以上、Marshal.BindToMonikerを使う方法が、CLSIDによりCOMオブジェクトを作る方法として簡単ではないかという話でした。私も、かつては「なぜCLSIDから実体を作るメソッドが.NETには用意されていない」と憤慨していました。ところが、すでに存在していたというのが真相だったのです。


スポンサード リンク

この記事のカテゴリ

  • ⇒ C#でCLSIDからオブジェクトを作る方法
  • ⇒ C#でCLSIDからオブジェクトを作る方法