配置
これまでこの記事では、COMタイプライブラリの生成にTLBEXP.EXEユーティリティを使ってきました。これは、.NETコンポーネントをCOMに公開する仕組みだけに注目するためでした。COMコンポーネントと同じように使える.NETコンポーネントを実際に作成する場合は、他のCOMコンポーネントと同じように登録を行う必要があります。
「regsvr32.exe」はご存知の通り、COMコンポーネントの登録と登録解除を行うユーティリティです。これは.NETコンポーネントには使用できません。代わりに、.NETの「regasm.exe」というユーティリティを使用します(regasmはRegister Assembly(アセンブリ登録)の略)。regasm.exeは、.NETコンポーネントを通常のCOMコンポーネントのように見せるレジストリエントリを追加します。
regasm.exeユーティリティは、VB6で使えるCOMタイプライブラリを生成する機能もあります。regasm.exeの/tlbオプションを指定すると、TLBEXP.EXEと同じ処理を実行します。従って、COM用の.NETオブジェクトを作成する場合、実はTLBEXPは必要ありません。regasmの/tlbオプションを使用してください。使い方の例を見てみましょう。Visual Studio .NET 2003コマンドプロンプトを開き、作成した.NETアセンブリのディレクトリに移動し、次のように入力します。
REGASM myassem.dll /tlb:com.myassem.tlb
作成したオブジェクトは、これでCOMコンポーネントとして登録され、VB6からこのコンポーネントの事前バインディング用に参照設定できるCOMタイプライブラリが生成されます。後は、COMから.NETアセンブリを見つけられるようにするだけです。
ローカル配置かGACか
作成した.NETアセンブリをCOMコンポーネントとして登録すると、COMからその.NETコンポーネントのインスタンスを作成しようとしたときに、.NETランタイムのコピーがロードされます。この.NETランタイムがアセンブリを発見できる必要があります。COM環境で実行している場合も、アセンブリを探す際の.NETの以下のルールは適用されます。
- まず、グローバルアセンブリキャッシュ(GAC)を探す。
- 次に、ローカルディレクトリを探す。
2番目は簡単ですが、あまり柔軟性がありません。例えば、.NETアセンブリをCOM exeクライアントと同じディレクトリにコピーすれば、ランタイムはこれを見つけることができます。ただし、VB6 IDEでビルドとデバッグを行うときは、VB6.EXEの場所がローカルディレクトリになります。従って、VB6 IDE内で実行しているかどうかによって、.NETアセンブリのコピー場所を変えなければなりません。VB6.EXEと同じディレクトリにファイルをコピーするのもよくないことです。.NETアセンブリを変更したら、両方の場所にコピーしなければならなくなります。このような理由から、COM相互運用機能では通常、アセンブリをグローバルアセンブリキャッシュ(GAC)に配置することが最善の方法となります。
アセンブリをGACに配置する前に、固定バージョン番号スキームと厳密名キーペアを指定する必要があります。固定バージョン番号スキームの指定は簡単です。AssemblyInfoファイルで、AssemblyVersion属性の値をデフォルトの「1.0.*」から「1.0.0.0」に変更します。アセンブリをGACに配置する場合、バージョン番号は重要です。「*」マスクのままにすると、VS .NETはプロジェクトをビルドするたびに新しい値を生成します。アセンブリを参照する他のプロジェクトは特定のバージョン番号を探すので、ビルドのたびにこれが変わっては問題です。従って、特定の値をハードコードし、アセンブリの新しいリリースを開発するときに必要に応じてバージョン番号を上げます。
次に、厳密名キーペアを生成します。これにはsn.exeツールを使用します。Visual Studio .NET 2003コマンドプロンプトから.NETプロジェクトのディレクトリに移動し、以下のコマンドを入力します。
sn -k mykey.snk
次に、AssemblyInfoで、AssemblyKeyFile属性を変更して「mykey.snk」ファイルを指すようにします。最後に、.NETコンポーネントをコンパイルし直します。これで、GACに追加する準備ができました。Visual Studio .NET 2003コマンドプロンプトから、.NETアセンブリのディレクトリに移動し、以下のコマンドを入力します。
gacutil -I myassembly.dll
これによってアセンブリはGACにインストールされます。これで、どのCOMクライアントがこの.NETコンポーネントのインスタンスを作成する場合も、ランタイムはこのアセンブリを見つけることができます。
推奨手順のまとめ
この記事では、多くの内容を説明しました。COM相互運用機能を簡単に利用する推奨手順をもう一度復習しましょう。
- COMに公開するメソッド用の.NETインターフェイスを定義する。
- そのインターフェイスの
Guid属性にGUIDを割り当てる。 - クラスの1番目のインターフェイスとしてインターフェイスを実装する。
- クラスの
Guid属性にGUIDを割り当てる。 - regasm/tlbexpが空のデフォルトインターフェイスを作成しないように、
ClassInterface(ClassInterfaceType.None)属性を追加する。 AssemblyVersion属性に特定のバージョン番号をハードコードする。- アセンブリの厳密名キーペアを生成し、
AssemblyKeyFile属性でこれを指すようにする。 - アセンブリをGACに追加する。
- regasmコマンドに/tlbオプションを指定して、COM用にアセンブリを登録し、COMタイプライブラリを生成する。
生成したタイプライブラリへの参照をVB6プロジェクトに追加すると、事前バインディングを利用できます。VBScriptなどのスクリプティングクライアントからもオブジェクトにアクセスできますが、その場合に使用できるのはデフォルトインターフェイスのメソッドのみです。
.NETコンポーネントを拡張する場合は、既存のインターフェイスは変更しないでください。新しいメソッドを追加する必要がある場合、新しいインターフェイスを作成し(GUIDも指定します)、そのインターフェイスを実装します。既存のインターフェイスを変更すると、そのインターフェイスを使用するように既にコンパイルされているクライアントが動作しなくなることがあります。
