.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には用意されていない」と憤慨していました。ところが、すでに存在していたというのが真相だったのです。
スポンサード リンク |