次の方法で共有


DLL 地獄の回避

ClickOnce と Reg-Free COM によるアプリケーションの配置の簡略化

Dave Templin


翻訳元: Simplify App Deployment with ClickOnce and Registration-Free COM (英語)

この記事は Visual Studio 2005 のプレリリース バージョンに基づいています。この記事のすべての情報は変更される可能性があります。

この記事で使用する技術: Visual Basic、COM、ClickOnce

サンプルコードのダウンロード: RegFreeCOM.exe (英語) (1,392KB)

この記事で取り上げる話題:

  • Reg-Free COM のメリット
  • Visual Studio 2005 を使用して既存の COM コンポーネントや ActiveX コントロールを分離する方法
  • Reg-Free COM の制限

目次

  1. Reg-Free COM の概要
  2. COM コンポーネントの分離
  3. 単純な COM コンポーネントの分離
  4. より複雑な例
  5. ネイティブ アセンブリ
  6. まとめ
  7. 補足記事: Reg-Free COM の制限

Visual Basic 6.0 や Active Template Library (ATL) で記述されたビジネス オブジェクトやユーザー コントロールを使用している場合は、COM を使用していることになります。Microsoft .NET Framework が導入されるまでは、COM が、Windows アプリケーションを構築するための主要なコンポーネント モデルでした。しかし、COM コンポーネントはコンピュータに対してグローバルに登録しないと機能しないため、COM コンポーネントを含むアプリケーションの配置は困難になることがあります。残念ながら、このグローバルな登録は思わぬ悪影響をもたらすことがあり、アプリケーションのコンポーネントを注意深く管理しないと、アプリケーションのライフサイクルの中でこの悪影響に悩まされることになります。それが、DLL 地獄 (DLL Hell) と呼ばれる問題です。

こうした要素は、一般に .NET では問題になりません。.NET ではコンポーネントを登録する必要がなく、アプリケーションのコンポーネントは他のアプリケーションから完全に分離されているか、グローバル アセンブリ キャッシュ (GAC) を通じてサイド バイ サイドで明確に管理されているからです。さまざまな移行ウィザードも用意されていますが、コードを .NET Framework に移行することが必ずしも現実的でない場合もあります。また、"壊れていないものを修理するな" という考え方もあります。したがって、既存の COM コンポーネントを .NET Framework のようなモデルを使って配置できればとても便利です。Windows XP 以降の Windows では、それが可能になっています。

Windows XP には、Reg-Free COM (登録不要の COM) と呼ばれる新しい COM アクティブ化モデルが導入されています。Reg-Free COM は、簡単に言うと、COM コンポーネントにとってのレジストリに置き換わるものです。これは、通常はシステム レジストリにインストールされる標準のコンポーネント登録情報のすべてを、アプリケーション本体と同じフォルダに格納されるファイルで表現することによって実現されます。

この記事では、既存の COM コンポーネントを使用するアプリケーションを、Visual Studio 2005 の新しい Reg-Free COM サポート機能を使用して配置する方法を紹介します。この機能を使用すると、そうしたアプリケーションを XCOPY や ClickOnce などの簡単な配置モデルを使って配置できるようになるため、COM コンポーネントの配置をときに困難にする従来の要因を克服できます。

ClickOnce は、.NET Framework 2.0 で導入される、Windows フォーム アプリケーションのための新しい配置技術です。この単純化されたアプリケーション配置モデルは、Web、ネットワーク共有、および CD などの配布メディアで利用できます。また、自動更新、安全かつ分離されたアプリケーション管理、構成可能なアプリケーション セキュリティなどにも対応しています。要するに、この技術によって、Windows フォーム アプリケーションの配置や更新を Web アプリケーションと同じように簡単かつ安全に行えるようになります。詳細については、Brian Noyes 氏による ClickOnce (英語)についての記事 (『MSDN Magazine』2004 年 5 月号) を参照してください。

ページのトップへ


1. Reg-Free COM の概要

従来は、アプリケーションで COM コンポーネントが使用されている場合は、コンポーネントが登録されていないとアプリケーションが機能しませんでした (図 1 を参照)。これは、アプリケーションがネイティブ アプリケーションの場合でも、.NET Framework ベースのアプリケーションの場合でも変わりません。アプリケーションが COM コンポーネントをインスタンス化すると、通常は、最終的に CoCreateInstance API が呼び出されます。CoCreateInstance は、簡単に言うと、アプリケーションによって指定された識別子 (CLSID) をレジストリで検索し、関連付けられているコンポーネント モジュールを見つけて、対応するクラスをアクティブにします。

図 1 従来の COM のアクティブ化

図 1 従来の COM のアクティブ化

コンポーネントをシステム レジストリに記述すると、それらを複数のアプリケーションの間で共有できるというメリットがあります。また、ネットワーク上の別のコンピュータにインストールされてアクティブになるようにコンポーネントを登録することもできます。アプリケーションでこうした機能を使用しない場合は、このグローバルな登録が、アプリケーションにとって大きな足かせにもなります。第 1 に、すべてのコンポーネントが正しく登録されるようにするには、通常、別途セットアップ プログラム (MSI や EXE のインストーラなど) を用意しなければなりません。また、コンポーネントの登録には、そのサイズによって数十から数千のレジストリ キーが含まれます。そして、それらのエントリが 1 つ破損しただけでも、アプリケーションが機能しなくなる可能性があります。アプリケーション、コンポーネント、および登録情報がコンピュータ全体に散らばっているために、アプリケーションの更新やアンインストールの管理が非常に困難になることがあります。複数のアプリケーションによって共有されているコンポーネントがある場合は、特にその傾向が強くなります。これはおそらく COM の最も一般的な問題で、そのために、一部のコンポーネントやアプリケーションが極端に脆弱で保守しにくいものとなっています。

Reg-Free COM では、従来の COM と違って、コンポーネントをシステム レジストリに別途記述する必要はありません。代わりにアプリケーション自体のスコープでコンポーネントの定義を管理することによって、上述のすべての問題を解消できます。これは、通常はシステム レジストリにインストールされる情報をすべて XML マニフェストで表現することによって行われます。XML マニフェストは、アプリケーション フォルダ内のファイルの 1 つにすぎません (図 2 を参照)。コンポーネントにマニフェストがあった場合、オペレーティング システムは、コンポーネントをアクティブにする際に、レジストリより先にマニフェストを確認します。

図 2 分離された COM のアクティブ化

図 2 分離された COM のアクティブ化

Reg-Free COM コンポーネント モデルは、プログラム (WindowsApplication1.exe など) と同じフォルダにアプリケーション マニフェスト (WindowsApplication1.exe.manifest など) を用意するだけで利用できます。これは、プログラムが実行されるたびに、Native Assembly Loader が実行ファイルの名前に基づいてマニフェスト ファイルを検索するからです。.NET アセンブリのコンポーネント モデルと同様、アプリケーション フォルダ以外の場所で外部コンポーネント定義が必要とされることはありません。1 つ以上のマニフェストがあった場合、Windows は、各識別子 (CLSID) を対応するコンポーネント ファイルに関連付ける内部テーブルを構築します。これは、アプリケーションのコードが実行される前の CreateProcess の段階で行われます。その後、アプリケーションがコンポーネントをインスタンス化すると、CoCreateInstance がシステム レジストリより先にこの内部テーブルを確認します。1 つ以上のマニフェストにすべてのコンポーネントが完全に記述されていれば、システム レジストリにコンポーネントが一切登録されていなくても、アプリケーションは問題なく機能します。

このモデルの最大のメリットは、COM コンポーネントがアプリケーション内に完全に分離される点にあります。同じ COM コンポーネント (またはその別のバージョン) を使用する他のアプリケーションがそのコンポーネントの登録を必要としている場合も、その影響を受けることはありません。また、アプリケーションの COM コンポーネントが他のアプリケーションによってアクセスされることもありません。したがって、Reg-Free COM のみを使用すれば、バージョンの競合による問題を回避できます。コンポーネントの GUID を変更する必要もありません。ただし、だからと言って、バージョン戦略をなしで済ましてよいことにはなりません。最後に、更新やアンインストールはこれ以上ないほど簡単になり、アプリケーション フォルダを削除したり置き換えたりするだけで済みます。

ちなみに、既存のコードで Reg-Free COM を利用する場合も、通常はコードを変更する必要はありません。必要となるのは、正しい構成のマニフェストを用意することだけです。実際、そもそも Reg-Free COM は、既存のネイティブ アプリケーション (Visual Basic 6.0、C++、またはある種の言語の組み合わせによって記述されたアプリケーション) を使用できるようにするために作られたものです。ただし、この記事の焦点は、.NET ベースのアプリケーションからの Reg-Free COM の使用にあります。

既に述べたように、Native Assembly Loader は、マニフェストによる COM コンポーネントのバインドに失敗すると、グローバルなコンポーネントの登録を使用します (それが存在する場合)。この動作によって、Reg-Free COM アプリケーションが正しく構成されていない場合も、正しく機能しているように見えてしまいます。したがって、アプリケーションが Reg-Free COM に対して正しく構成されているかどうかを検証する際には、クリーンなコンピュータでテストすることをお勧めします。そうでない場合は、アプリケーションが完全に Reg-Free COM で実行されていることを確認するには、アプリケーションを構成するすべてのコンポーネントを事前に登録解除する必要があります。

ページのトップへ


2. COM コンポーネントの分離

Visual Studio 2005 では、スイッチの切り替え 1 つで任意の COM コンポーネントを分離できる新機能が導入されています。この機能は、コンポーネントのタイプ ライブラリとコンポーネントの登録からマニフェストを自動的に生成することによって実現されています。したがって、COM コンポーネントを分離するにはそのコンポーネントが開発者のコンピュータに登録されている必要があるという点に注意する必要があります。エンドユーザーのコンピュータにコンポーネントを登録する必要はなくなります。

Visual Studio 2005 のすべての COM 参照には、Isolated という新しいプロパティがあります。このプロパティの既定値は False で、通常の登録済み COM 参照として扱うように指定されています。このプロパティを True に設定すると、ビルド時にコンポーネントのマニフェストが生成されます。また、対応するコンポーネント ファイルがアプリケーション フォルダにコピーされます。マニフェスト ジェネレータは、分離された COM 参照を見つけると、コンポーネントのタイプ ライブラリの CoClass エントリをすべて列挙し、各エントリを対応する登録データに関連付けます。このようにして、すべての COM クラスのマニフェスト定義が自動的にファイルに生成されます。

COM コンポーネントを分離する機能は、主として、Visual Basic .NET アプリケーションや C# アプリケーション内の Visual Basic 6.0 COM コンポーネントで Reg-Free COM 配置を実現するために作られたものです。とはいえ、この機能は Visual Basic 6.0 コンポーネントのみに制限されるものではなく、Reg-Free COM での使用に適した任意の COM コンポーネントで使用できます。ただし、すべてのアプリケーションやコンポーネントのシナリオが Reg-Free COM での使用に適しているわけではありません。詳細については、補足記事「Reg-Free COM の制限」を参照してください。

この後の 2 つのセクションでは、この機能がどのように動作するのかを実際に見てみます。まず、Visual Basic 6.0 で単純な COM コンポーネントを作成し、それを Reg-Free COM を使って配置する方法を紹介します。次に、それよりやや複雑な例を使用して、いくつかの ActiveX コントロールを Reg-Free COM でも使用できるようにする方法を紹介します。

ページのトップへ


3. 単純な COM コンポーネントの分離

まず、Visual Basic 6.0 で単純な COM コンポーネントを作成します。Visual Basic 6.0 をお持ちの方は、ごく簡単な手順でコンポーネントを手動で作成できます。または、単純にこの記事のサンプル コードから VB6Hello.dll ファイルをコピーして、コマンド プロンプトで「regsvr32 VB6Hello.dll」と入力して登録してもかまいません。そのほか、COM DLL を作成できる ATL やその他の開発環境を使用することもできます。

Visual Basic 6.0 を使用して、"VB6Hello" という名前の新しい ActiveX DLL を作成し、Class1 コード モジュールに次のコードを追加します。

Public Sub SayHello()
MsgBox "Hello from Visual Basic 6.0"
End Sub

[File] メニューの [Make] をクリックして、VB6Hello.dll をビルドします。Reg-Free COM でサポートされるプロジェクトの種類は ActiveX DLL と ActiveX コントロールだけなので注意してください。ActiveX EXE と ActiveX ドキュメントは、Reg-Free COM では使用できません (補足記事を参照)。

次に、この COM コンポーネントを Windows フォーム アプリケーションから参照します。Visual Studio 2005 を起動し、"RegFreeComDemo1" という名前の新しい Visual Basic Windows アプリケーション プロジェクトを作成します。必要に応じて C# や J# を使用してもかまいません。コードはごく単純なので、それぞれの言語に合わせて簡単に変更できます。[プロジェクト] メニューの [参照の追加] をクリックし、コードから生成された VB6Hello.dll コンポーネントを指定します。続いて、"Say Hello" という名前のボタンをフォームに追加します。ボタンをダブルクリックしてコード ウィンドウに移動し、次のコードを追加します。

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As _
System.EventArgs) Handles Button1.Click
Dim Vb6Obj As New VB6Hello.Class1
Vb6Obj.SayHello()
End Sub

F5 キーを押してアプリケーションを実行します。ボタンをクリックすると、図 3 のようなメッセージ ボックスが表示されるはずです。

図 3 RegFreeComDemo1

図 3 RegFreeComDemo1

Reg-Free COM の話に入る前に、いくつかの点について確認しておきましょう。まず、ビルドによって生成されたファイルのセットを調べます。Interop.VB6Hello.dll、RegFreeComDemo1.exe、および RegFreeComDemo1.exe.config というファイルがあります。RegFreeComDemo1.exe は、もちろん、メイン プログラム ファイルです。Interop.VB6Hello.dll は、ビルドによって自動的に生成された COM 相互運用アセンブリです。表示されていないその他のファイルはサポート ファイルで、ここでの議論には関係ありません。ただし、VB6Hello.dll COM コンポーネントがこのフォルダに含まれていないという点には注目する必要があります。

COM コンポーネントを登録解除して (たとえば、コマンド プロンプトで「regsvr32 /u VB6Hello.dll」と入力します)、RegFreeComDemo1.exe を Visual Studio IDE の外部から実行してみます。今度は、ボタンをクリックするとアプリケーションがエラーになるはずです。COM コンポーネントを登録解除した場合は、先に進む前にコンポーネントを再登録する必要があります。そうしないと、Visual Studio 2005 内でアプリケーションをリビルドできません。

アプリケーションによって使用されている各 COM コンポーネントは、プロジェクト内で COM 参照として表されます。これらの参照は、[ソリューション エクスプローラ] ウィンドウの [参照設定] ノードに表示されます。このノードが表示されていない場合は、[プロジェクト] メニューの [すべてのファイルを表示] をクリックします。

では、この COM コンポーネントを分離してみましょう。[ソリューション エクスプローラ] ウィンドウの [参照設定] ノードを展開します。[参照設定] ノードの下の [VB6Hello] 項目を選択し、[プロパティ] ウィンドウで Isolated プロパティを True に設定します (図 4 を参照)。[プロパティ] ウィンドウが表示されていない場合は F4 キーを押します。

図 4 分離

図 4 分離

F5 キーを押すと、アプリケーションは予想どおりに動作します。ただし、今度は Reg-Free COM で実行されています。このことを確かめるために、先ほどと同じように VB6Hello.dll コンポーネントを登録解除し、RegFreeComDemo1.exe を Visual Studio IDE の外部で実行してみます。今度は、ボタンをクリックするとアプリケーションが正常に動作します。アプリケーション マニフェストの名前を一時的に変更すると、再びアプリケーションがエラーになります。

ここで、ビルドによって生成されたファイルをもう一度見てみましょう。Interop.VB6Hello.dll、RegFreeComDemo1.exe、RegFreeComDemo1.exe.config、RegFreeComDemo1.exe.manifest、および VB6Hello.dll の 5 つのファイルがあります。最後の 2 つのファイルは、COM コンポーネントを分離した後に新たに加わったものです。今度は、VB6Hello.dll がアプリケーション フォルダにコピーされています。もう 1 つの RegFreeComDemo1.exe.manifest は、アプリケーション マニフェスト ファイルです。Reg-Free COM が機能するのは、このマニフェスト ファイルのおかげです。このファイルのセットを、.NET Framework 2.0 のみがインストールされた別の Windows XP コンピュータに XCOPY すると、コンポーネントを何も登録しなくてもアプリケーションが実行されます。Windows XP には Visual Basic 6.0 ランタイム ライブラリが含まれているため、MSVBVM60.dll や OLEAUT32.dll などのインストールに関する心配もいりません。

アプリケーション マニフェストの実体は XML ドキュメントなので、任意のテキスト エディタを使って調べることができます。図 5 のコードは、このファイルの内容を表しています。ただし、まったく同じファイルを使用していない場合は、ハッシュと GUID の識別子は異なります。<comClass> と <typelib> というサブ要素を持つ <file> 要素に注目してください。ここからわかるように、クラスとタイプ ライブラリの GUID はマニフェストで宣言されています。これは、従来レジストリに登録されていたのと同じ情報です。

図 5 Reg-Free COM のアプリケーション マニフェスト

<?xml version="1.0" encoding="utf-8"?>
<assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 
assembly.adaptive.xsd" manifestVersion="1.0" 
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" 
xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" 
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" 
xmlns="urn:schemas-microsoft-com:asm.v1" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <assemblyIdentity name="RegFreeComDemo1.exe" 
   version="1.0.0.0" type="win32" />
  <file name="VB6Hello.dll" asmv2:size="20480">
    <hash xmlns="urn:schemas-microsoft-com:asm.v2"> •••  </hash>
    <typelib tlbid="{ea995c49-e5d0-4f1f-8489-31239fc9d9d0}" version="2.0" 
      helpdir="" resourceid="0" flags="HASDISKIMAGE" />
    <comClass clsid="{97b5534f-3b96-40a4-88b8-19a3bf4eeb2e}" 
      threadingModel="Apartment" progid="VB6Hello.Class1"
      tlbid="{ea995c49-e5d0-4f1f-8489-31239fc9d9d0}" />
  </file>
</assembly>

ClickOnce を使用したことがある方は、ClickOnce のアプリケーション マニフェストが上で説明したのと同じファイルに格納されていることをご存じかもしれません。ここから、ClickOnce と RegFree COM の定義は同じファイルに共存できることがわかります。では、この同じアプリケーションを、ClickOnce を使って発行するとどのようになるのか見てみましょう。Visual Studio 2005 のソリューション エクスプローラでプロジェクトを右クリックし、[発行] をクリックして、発行ウィザードを使ってプロジェクトを発行します。ClickOnce バージョンのアプリケーション マニフェストの内容は、この記事のダウンロード ファイルで確認できます。

このアプリケーション マニフェストには、単純なアプリケーション マニフェストの定義のスーパーセットが含まれています。先ほどと同じように、<comClass> と <typelib> というサブ要素を持つ <file> 要素が含まれていますが、今度は、アプリケーション全体のすべてのファイルの定義が含まれています。さらに、ClickOnce では、アプリケーションの整合性を保証するために、すべてのアプリケーション ファイルとアセンブリのハッシュが必要になります。もう 1 つの重要な違いは、すべての ClickOnce アプリケーションは署名を必要とするという点です。XCOPY 配置のみを目的とするマニフェストでは、署名は必要ありません。アプリケーションのセキュリティは、完全信頼として定義されています。ネイティブ コード (すべての COM コンポーネントはネイティブ コードです) を直接参照するアプリケーションは、必然的に完全信頼になります。部分信頼が使用されている COM 参照があると、Visual Studio 2005 でビルド警告が表示されます。

最後に、Reg-Free COM を使用する場合は、最低限必要な OS のバージョンが自動的に Windows XP に設定されることを認識しておく必要があります。エンドユーザーが以前のバージョンの Windows を使用していた場合は、このアプリケーションを使用するには新しいバージョンの Windows をインストールする必要があるという内容のエラー メッセージが表示されて、アプリケーションをインストールできません。

ClickOnce と Reg-Free COM の両方の定義を含むアプリケーション マニフェストを見ると、ClickOnce のアプリケーション マニフェストの構造に関する興味深い事実が明らかになります。つまり、それらが、Windows XP 以降のオペレーティング システムに導入された既存のマニフェスト形式の拡張であることがわかります。

この例では、Reg-Free COM を使用して単純なコンポーネントを呼び出す方法を紹介しました。ビジネス オブジェクトなどのより複雑なコンポーネントでも、同じように簡単に行うことができます。次の例では、ActiveX コントロールを Reg-Free COM でも使用できるようにする方法を紹介します。

ページのトップへ


4. より複雑な例

この例では、この記事のサンプル コードに含まれている、"VB6ControlTest" というビルド済みコンポーネントを使用します。これは、Visual Basic 6.0 開発環境に含まれている他のいくつかの ActiveX コントロールを使用する Visual Basic 6.0 ユーザー コントロールです。ここで、VB6ControlTest.ocx をサンプル コードからお使いのコンピュータにコピーして、登録してください。

Visual Studio 2005 を起動し、"RegFreeComDemo2" という名前の新しい Visual Basic Windows アプリケーション プロジェクトを作成します。次に、VB6ControlTest コンポーネントをプロジェクトに追加します。ただし、これは ActiveX コントロールなので、ツールボックスを通じて追加する必要があります。[表示] メニューの [ツールボックス] をクリックします。[General] タブを右クリックし、[Choose Items] をクリックします。[Choose Toolbox Items] ダイアログ ボックスで、[COM] タブをクリックし、[VB6ControlTest.ocx] を指定します。VB6ControlTest.UserControl1 コントロールをフォームにドラッグし、タブ コントロール全体が表示されるようにサイズを調整します。すべて完了すると、図 6 のような画面になるはずです。

図 6 RegFreeComDemo2 プログラム

図 6 RegFreeComDemo2 プログラム

それでは、ActiveX コントロールをすべて分離してみましょう。[ソリューション エクスプローラ] ウィンドウの [参照設定] ノードを展開します。VB6ControlTest と AxVB6ControlTest の両方の項目について、Isolated プロパティを True に設定します。これでユーザー コントロールが分離されましたが、ユーザー コントロールが参照しているコントロールも分離する必要があります。そのためには、.NET ベース アプリケーションからそれらの追加コントロールへの参照を追加し、それらのコントロールを分離するだけです。[参照の追加] コマンドを使用して [COM] タブから以下の項目を追加し、それらを分離します。

  • Microsoft Common Dialog Control 6.0 (SP6)
  • Microsoft Rich Textbox Control 6.0 (SP4)
  • Microsoft Tabbed Dialog Control 6.0 (SP4)
  • Microsoft Windows Common Controls 6.0 (SP6)
  • Microsoft Windows Common Controls-2 6.0 (SP3)

分離するコントロールの選択には注意が必要です。1 つの基準として、純粋な UI ウィジェットであるコントロールはたいてい Reg-Free COM でも問題なく動作します。ただし、必ずアプリケーションで完全にテストして確認するようにしてください。詳細については、補足記事を参照してください。

発行ウィザードを使用してプロジェクトを発行します。.NET Framework 2.0 のみがインストールされている別のコンピュータがある場合は、ここでそのコンピュータに移動して、この ClickOnce アプリケーションをインストールします。これで、ClickOnce を使用してスムーズに配置できる、複数の ActiveX コントロールを含む .NET アプリケーションが完成しました。このアプリケーションは、コンピュータに詳しくないユーザーでも難なくインストールできます。また、DLL 地獄の心配もありません。

ページのトップへ


5. ネイティブ アセンブリ

Isolated プロパティを使用すると、まだマニフェストのない既存の COM コンポーネントを実に簡単に分離および配置できます。しかし、ベンダーやコンポーネント所有者によってコンポーネントのマニフェストが提供されている場合は、直接そのネイティブ アセンブリを参照できます。可能な限り、Isolated フラグを使用するより、コンポーネントの作成者によって提供されているマニフェストを使用するようにしてください。

Visual Studio 2005 は、Visual Basic .NET や C# からネイティブ アセンブリへの参照をサポートしています。プロパティ ウィンドウで参照の File Type プロパティが Native に設定されていると、ネイティブ参照が作成されます。ネイティブ参照を追加するには、[プロジェクト] メニューの [参照の追加] をクリックし、[参照] タブをクリックして、マニフェストの場所に移動します。一部のコンポーネントでは、マニフェストが DLL の内部に配置されています。そのような場合は、DLL 自体を選択するだけでかまいません。コンポーネントにマニフェストが埋め込まれていることが検出されれば、自動的にネイティブ参照として追加されます。

なお、ネイティブ アセンブリでは、コンポーネントに関連付けられている追加のファイルを定義できます。また、他の依存ネイティブ アセンブリを参照している場合もあります。そのような場合は、ネイティブ アセンブリおよびファイルの任意の複雑さの依存グラフを、独自に作成したマニフェストにカプセル化することができます。マニフェストで表現されているそうしたファイルや依存ネイティブ アセンブリは、参照先コンポーネントと同じフォルダにあれば自動的に含まれます。

マニフェストの形式はプレーン XML です。したがって、コンポーネント所有者は、コンポーネントをネイティブ アセンブリにしたければマニフェストを手動で作成できます。ハッシュ コードの計算、マニフェストの埋め込み、ATL RGS スクリプトからの Reg-Free COM エントリの生成などのタスクは、プラットフォーム SDK の MT ツールを使用して実行できます。

Reg-Free COM やネイティブ参照は、もちろん、Visual Basic .NET や C# のクラス ライブラリ内から使用できます。興味深いことに、結果となるコンポーネントは、マネージ アセンブリ (.dll) とネイティブ アセンブリ (.manifest) の両方で構成されています。別のプロジェクトからこのコンポーネントを参照する場合、コンポーネントを正しく使用するには 2 つの参照が必要になります。プロジェクト間参照を使用する場合 ([参照の追加] をクリックして、コンポーネントを同じソリューション内のプロジェクトとして選択する場合など) は、両方のアセンブリが自動的に参照されます。それ以外の場合は、[参照の追加] を 2 回実行する必要があります。1 回目には DLL を指定し、2 回目にはマニフェストを指定します。

ページのトップへ


6. まとめ

Reg-Free COM は、COM コンポーネントを使用するアプリケーションの配置に伴う困難を克服するための優れた手段となります。ActiveX コントロールだけでなく、ビジュアル オブジェクトではないビジネス オブジェクトにも使用できます。これにより、ネイティブ コンポーネントや COM コンポーネントが、アプリケーションの分離の面でも配置の容易さの面でも、マネージ コンポーネントと同等になります。唯一の大きな欠点は、プラットフォームの最小要件が Windows XP 以上と厳しくなることです。しかし、新しいプラットフォームに移行するコンピュータが増えるにつれて、これらの新機能によってもたらされるメリットはますます大きなものとなっています。

ページのトップへ


7. 補足記事: Reg-Free COM の制限

Reg-Free COM には、従来の配置技術に比べて明らかなメリットがいくつかあります。しかし、最初に確認しておく必要がある制限や注意点もあります。

もちろん、Reg-Free COM の最大の制限は、Windows XP 以降のオペレーティング システムでしか機能しないことです。また、コンポーネントがコア オペレーティング システムに読み込まれる方法の変更も必要となります。残念ながら、Reg-Free COM には下位レベルのサポート層はありません。

すべてのコンポーネントが Reg-Free COM での使用に適しているわけではありません。次の条件に 1 つでも当てはまる場合、そのコンポーネントは適しているとは言えません。

  • コンポーネントがアウトプロセス (ActiveX EXE) サーバーの場合。サポートされるのは DLL のみです。
  • コンポーネントがシステム コンポーネントまたはオペレーティング システムの一部である場合 (XML、Data Access、Internet Explorer、または DirectX の各コンポーネントなど)。たとえば、Microsoft XML (MSXml.dll) や Microsoft Internet Controls (SHDocVw.dll) などのコンポーネントを分離しようとするべきではありません。これらのコンポーネントは、オペレーティング システムの一部であるか、別の再配布可能パッケージでインストールされる可能性があります。
  • コンポーネントが Microsoft Office などのアプリケーションの一部である場合。たとえば、Microsoft Word Object Model や Microsoft Excel Object Model などのコンポーネントを分離しようとするべきではありません。これら 2 つのコンポーネントは Office の一部であり、完全な Office 製品がインストールされているコンピュータでしか使用できません。
  • コンポーネントがアドインやスナップインとして使用するためのものである場合 (Office のアドインや Web ブラウザのコントロールなど)。一般にそのようなコンポーネントは、ホスト環境によって定義されるなんらかの登録スキームを必要としますが、それらはマニフェストの範囲を超えています。もう 1 つの問題は、任意のアプリケーションが、分離したコンポーネントを認識するように作られていない可能性があることです。たいていのアプリケーションでは、マニフェストを通じてコンポーネントを参照する方法は用意されていません。
  • コンポーネントが物理的または仮想的な共有システム リソースを管理している場合。 たとえば、複数のアプリケーションの間で共有されているなんらかのデータ接続を管理している場合や、印刷スプーラのデバイス ドライバを管理している場合などが考えられます。

一般にデータ アプリケーションは、独立した Data Access 再配布可能パッケージが事前にインストールされていないと実行できません。Microsoft ADO Data Control、Microsoft RemoteData Control、Microsoft DAO Object Library、Microsoft OLE DB、Microsoft Data Access Components (MDAC) などのコンポーネントは、分離しようとするべきではありません。Visual Studio 2005 では、新しい Visual Studio 2005 Bootstrapper 機能によって、データ アプリケーションを適切な再配布可能パッケージと共に配置するプロセスが簡単になっています。MDAC や SQL Server Express を使用している場合は、プロジェクト プロパティの [Publish] ページの [Prerequisites] ダイアログで対応する項目をオンにするだけで済みます。

場合によっては、コンポーネントの開発者が、Reg-Free COM での使用に合わせてコンポーネントを再設計することも可能です。Reg-Free COM での使用に適していないコンポーネントがある場合でも、Bootstrapper を使用して、標準の登録スキームを通じてそれらのコンポーネントを使用する ClickOnce アプリケーションをビルドおよび発行することはできます。詳細については、Visual Studio 2005 Bootstrapper (英語)についての Sean Draine 氏の記事 (『MSDN Magazine』2004 年 10 月号) を参照してください。

記事の本文で述べたとおり、分離の機能は、コンポーネントのタイプ ライブラリと登録を調べることによって実現されます。COM コンポーネントを分離する過程で、標準から外れたコンポーネントの登録が見つかった場合は、ビルド警告が表示されます。マニフェストのスキーマは、標準の COM 登録のセマンティクスのみをサポートする閉じたモデルです。そうした警告が表示される場合、そのコンポーネントは、Reg-Free COM での使用に適していない可能性があります。

COM コンポーネントを分離できるのは、1 つのアプリケーションにつき 1 回だけです。たとえば、同じアプリケーションの一部である 2 つの異なるクラス ライブラリ プロジェクトから同じ COM コンポーネントを分離することはできません。そうしようとするとビルド警告が表示され、実行時にアプリケーションの読み込みに失敗します。この問題の回避策として、マイクロソフトでは、COM コンポーネントを 1 つのクラス ライブラリでカプセル化することを推奨しています。

いくつかのシナリオでは、アプリケーションの配置の際には必要なくても、開発者のコンピュータでは COM の登録が必要になります。Isolated 機能では、ビルド時にマニフェストを自動生成するために、常に開発者のコンピュータでの COM コンポーネントの登録が必要になります。登録情報を収集してビルド時に自己登録を実現する機能はありません。また、タイプ ライブラリで明示的に定義されていないクラスは、マニフェストには反映されません。ネイティブ参照など、既存のマニフェストを持つ COM コンポーネントを使用する際には、開発時にコンポーネントを登録する必要はありません。ただし、コンポーネントが ActiveX コントロールで、ツールボックスや Windows フォーム デザイナで使用する場合は、登録が必要です。


Dave Templin はマイクロソフトの Visual Basic チームの開発者で、Visual Studio 2005 の新しい ClickOnce のサポート全体を統括しています。オンラインでの連絡先は、blogs.msdn.com/dtemp (英語)です。


この記事は、MSDN マガジン - 2005 年 4 月号からの翻訳です。

ページのトップへ