2006 年 7 月 10 日 19 時 16 分

カラム登録の自動化


このアーカイブは同期化されません。 mixi の日記が更新されても、このアーカイブには反映されません。


一般的に、COM のライブラリ(DLL)は、
regsvr32.exe というシステム附属のツールで登録される。
regsvr32 は DLL の特定の関数を呼び出すだけなので、
COM クラスの登録等は、DLL 側が関数を用意して行う。
つまり、製作者は自由に登録処理を書くことができる。

.NET で作った場合は、純粋な COM DLL は作成できないため、
regsvr32 では登録できず、.NET Framework 附属の、
regasm.exe というツールで登録される。

しかし、regasm は regsvr32 と違い、
アセンブリが COM 用に公開しているクラスを
自動的に登録してくれるため、製作者は何もする必要がない。

通常はこれで構わないのだが、
COM クラスの登録以外に登録作業が必要な場合、
ちょっと困ったことになる。

今作っている LoaferShellEx.dll アセンブリは、
カラムの登録はレジストリファイルを使って行っていたが、
DLL として配布することを考えた場合、
レジストリファイルを渡すのは少し不自然だ。

どうせ regasm は実行しなければならないので、
できれば、regasm 一発で行えないだろうか。

.NET にはこういった用途のために、
regasm による登録・登録解除時に、
特定のメソッドを呼び出すという機能がある。
これを使えば、追加作業を行うことができるのだ。

追加登録作業を行わせるためには、
「COM クラスとして登録を行うクラス」に、
以下のようなメソッドを追加する。
今回の場合は、ColumnProvider クラスになる。

    [ComRegisterFunction]
    private static void Register(Type t) {
        // TODO: 登録処理
    }

    [ComUnregisterFunction]
    private static void Unregister(Type t) {
        // TODO: 登録解除処理
    }

メソッドは静的で、アクセス制御は private が推奨される。
何と、メソッドはアクセス制御無視で呼び出されるのだ。
また、シグネチャが合っていれば、名前は何でも構わない。

そして、regasm がこれらのメソッドを見つけられるように、
メソッドに ComRegisterFunctionAttribute と、
ComUnregisterFunctionAttribute の属性を追加する。

このようにしておくと、ColumnProvider クラスが
登録、登録解除される際に、それぞれ
Register、Unregister メソッドが呼び出されることになる。
引数である Type 型は、クラス自身の型を表す。
クラスの属性等にアクセスする際に利用するが、
通常は使う必要はない。

では、荒っぽいテストをしてみよう。

    [ComRegisterFunction]
    private static void Register(Type t) {
        System.Windows.Forms.MessageBox.Show("Register: " + t.ToString());
    }

    [ComUnregisterFunction]
    private static void Unregister(Type t) {
        System.Windows.Forms.MessageBox.Show("Unregister: " + t.ToString());
    }

この状態でビルドしてみよう。

「Register: LoaferShellEx.Column.ColumnProvider」

と表示された。

もう一度ビルドしてみよう。

「Unregister: LoaferShellEx.Column.ColumnProvider」
「Register: LoaferShellEx.Column.ColumnProvider」

と表示された。

ちゃんと呼び出されていることが解る。

もし表示されない場合は、メソッドのシグネチャが違うか、
登録されるクラス内に定義していないか、
プロジェクトのプロパティの「COM 相互運用機能に登録」が、
False になっているということだ。

また、この挙動から、.NET はビルドする前に、
DLL を一度登録解除していることも解る。

.NET はビルドに失敗した場合は登録作業を行わないので、
これを利用して、ソースに適当に書き換えて、
ビルド時にエラー(文法等)が起きるようにすれば、
登録解除だけを行うことができる。



Copyright (c) 1994-2007 Project Loafer. All rights reserved.