Registration-Free のアクティブ化.NET-Based コンポーネント: チュートリアル
Steve White
開発者向けの Premier サポート(Microsoft UK)
Leslie Muller
グローバルITリサーチ & 開発、クレディスイスファーストボストン
2005 年 7 月
適用対象:
Microsoft Windows Server 2003
Microsoft Windows XP Service Pack 2
Microsoft .NET Framework バージョン 1.1
Microsoft Visual Studio .NET 2003
Microsoft Visual Basic 6.0
この記事に付属するサンプルをダウンロードします。MSDNRegFreeNet.msi。
コンテンツ
紹介
Registration-Free COM の用語
サンプルの実行
COM サーバーとしての .NET アセンブリのビルド
クライアントのビルド
Registration-Free アクティブ化
トラブルシューティング
結論
その他の資料
紹介
登録不要の COM は、Microsoft Windows XP (.NET Framework ベースのコンポーネント用 SP2) および Microsoft Windows Server 2003 プラットフォームで使用できるメカニズムです。 名前が示すように、このメカニズムを使用すると、COM コンポーネントを登録しなくても、コンピューターに COM コンポーネントを簡単に (XCOPY など) デプロイできます。
ターゲット プラットフォームでは、プロセスとその依存モジュールを初期化する段階の 1 つは、関連付けられている マニフェスト ファイル、アクティブ化コンテキストと呼ばれるメモリ構造に読み込みます。 対応するレジストリ エントリがない場合は、COM ランタイムに必要なバインディングとアクティブ化の情報を提供するアクティブ化コンテキストです。 アクティブ化コンテキスト APIを使用してアクティブ化コンテキストを自分で作成してファイルの使用を無効にしない限り、COM サーバーまたはクライアントで特別なコードは必要ありません。
このチュートリアルでは、Visual C++ と Visual Basic 6.0 で記述されたネイティブ COM クライアントから、単純な .NET アセンブリを構築し、登録済みと登録解除の両方で使用します。 ソース コードとサンプルをダウンロードしてすぐに動作を確認することも、チュートリアルに従って自分でステップ バイ ステップでビルドすることもできます。
Registration-Free COM の用語
.NET テクノロジに精通しているユーザーは、アセンブリ という用語に慣れている、1 つのモジュールが 1 つのユニットとしてデプロイされ、名前が付けられ、バージョン管理され、1 つのモジュールにセットを定義する マニフェスト が含まれていることを意味します。 登録不要の COM では、アセンブリ と
登録不要の COM では、アセンブリ を使用して、1 つ以上の PE モジュール (ネイティブ またはマネージド) のセットを 1 つのユニットとしてデプロイ、名前付け、バージョン管理することを意味します。 登録不要の COM では、マニフェスト を使用して、XML を含む .manifest 拡張子を持つテキスト ファイルを参照します。このファイルは、アセンブリ (アセンブリ マニフェスト) の ID とそのクラスのバインドとアクティブ化の詳細を定義するか、1 つ以上のアセンブリ ID 参照と共に アプリケーション (アプリケーション マニフェスト) の ID を定義します。 アセンブリ マニフェスト ファイルにはアセンブリの名前が付けられ、アプリケーション マニフェスト ファイルにはアプリケーションの名前が付けられます。
side-by-side (SxS) アセンブリ という用語は、マニフェスト ファイルを介して同じ COM コンポーネントの異なるバージョンの構成を指し、登録する必要なく、異なるスレッドによって同時に読み込むことができます。
サンプルの実行
サンプル コードをダウンロードして抽出すると、\deployed
COM サーバーとしての .NET アセンブリのビルド
手順 1
C# コード
using System;
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: Guid("[LIBID_SideBySide]")]
namespace SideBySide
{
[Guid("[IID_ISideBySideClass]")]
public interface ISideBySideClass
{
string Version();
}
[Guid("[CLSID_SideBySideClass]")]
public class SideBySideClass : ISideBySideClass
{
public string Version()
{
return "1.0.0-C#";
}
}
}
Visual Basic .NET コード
Imports System
Imports System.Reflection
Imports System.Runtime.InteropServices
<Assembly: AssemblyVersion("1.0.0.0")>
<Assembly: Guid("[LIBID_SideBySide]")>
<Guid("[IID_ISideBySideClass]")> _
Public Interface ISideBySideClass
Function Version() As String
End Interface
<Guid("[CLSID_SideBySideClass]")> _
Public Class SideBySideClass
Implements ISideBySideClass
Function Version() As String Implements ISideBySideClass.Version
Version = "1.0.0-VB.NET"
End Function
End Class
プロジェクトに特有の GUID 値をプレースホルダーの形式で記述しました。 guidgen ツールを使用して一意の GUID を生成する必要があります。これは、後でプレースホルダーを使用するときに使用するそれぞれの値になります。
手順 2
ビルド時にタイプ ライブラリが生成されて登録されるように、プロジェクトの COM 相互運用機能の登録 設定を true に設定します。
手順 3
リリース ビルドを生成し、\deployedに SideBySide.dll をコピーします。
クライアントのビルド
次の手順では、クライアントをビルドします。このチュートリアルでは、
手順 4 (オプション A: Visual C++)
SideBySide プロジェクトのフォルダーを基準にして、クライアント と呼ばれる新しい Visual C++ Win32 コンソール プロジェクト を兄弟フォルダーに作成します。
stdafx.h
#define _WIN32_DCOM
また、stdafx.h ファイルの下部に次の行を追加します。
import "[path]\SideBySide.tlb" no_namespace
ここで、[path] は、SideBySide アセンブリをビルドしたときに生成されたタイプ ライブラリへの相対パスである必要があります。 通常、このパスは、手順 1 で C# または Visual Basic .NET プロジェクトのどちらを選択したかによって異なります。
client.cpp の内容を次のコードに置き換えます。
#include "stdafx.h"
#include <iostream>
using namespace std;
void ErrorDescription(HRESULT hr)
{
TCHAR* szErrMsg;
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&szErrMsg, 0, NULL) != 0)
{
cout << szErrMsg << endl;
LocalFree(szErrMsg);
}
else
cout << "Could not find a description for error 0x"
<< hex << hr << dec << endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
CoInitializeEx(0, COINIT_MULTITHREADED);
{
ISideBySideClassPtr ptr;
HRESULT hr =
ptr.CreateInstance(__uuidof(SideBySideClass));
if (SUCCEEDED(hr))
{
cout << ptr->Version() << endl;
}
ErrorDescription(hr);
char c;
cin >> c;
}
CoUninitialize();
return 0;
}
リリース ビルドを生成し、\deployedに \release\client.exe をコピーします。
手順 4 (オプション B: Visual Basic 6.0)
Visual Basic 6.0 Standard EXE プロジェクト
フォーム デザイナーでメイン フォームをダブルクリックし、Sub Form_Load()内に次のコードを貼り付けます。
Dim obj As New SideBySideClass
Dim isxs As SideBySide.ISideBySideClass
Set isxs = obj
MsgBox isxs.Version()
ファイル
手順 5
現時点では、\deployed フォルダーには、中間ファイルとは別に、client.exe と SideBySide.dllのみを含める必要があります。後者はビルド プロセスによって登録されます。 このような状況でサーバーとクライアントが連携していることを確認するには、\deployed\client.exe を実行し、予想される出力 "1.0.0-C#" または "1.0.0-VB.NET" に注意してください。
手順 6
このチュートリアルでは、登録不要 COM regasm /u SideBySide.dll
。
手順 7
前の手順で発生した影響を確認するには、\deployed\client.exe をもう一度実行すると、"クラスが登録されていません" または "実行時エラー '429': ActiveX コンポーネントはオブジェクトを作成できません" というメッセージが表示されます。 この段階では、COM ランタイムがレジストリで必要な情報を見つけることに不満を感じていましたが、代替手段で情報を利用できるようにはまだありません。 この問題は、次の手順で解決します。
Registration-Free アクティブ化
手順 8
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
type = "win32"
name = "client"
version = "1.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="SideBySide"
version="1.0.0.0" />
</dependentAssembly>
</dependency>
</assembly>
手順 9
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
type="win32"
name=" SideBySide"
version="1.0.0.0" />
<clrClass
clsid="{[CLSID_SideBySideClass]}"
progid="SideBySide.SideBySide"
threadingModel="Both"
name="SideBySide.SideBySideClass" >
</clrClass>
</assembly>
次のタスクでは、上記のアセンブリ マニフェスト ファイルを Win32 リソースとして SideBySide アセンブリに埋め込みます。 現時点では、これは Windows XP では必須ですが、Windows Server 2003 では必須ではありません。 Windows Server 2003 では、アセンブリ マニフェスト ファイルをアセンブリと共に配置するだけで、
手順 10
#include <windows.h>
#define MANIFEST_RESOURCE_ID 1
MANIFEST_RESOURCE_ID RT_MANIFEST SideBySide.manifest
windows.h ファイルとその依存関係は、Platform SDK (Core SDK セクション) または Visual C++ をインストールするときに使用できます。 ここで必要 windows.h の定義は次のとおりです。
#define RT_MANIFEST 24
その結果、SideBySide.rc の内容 解決されます。
1 24 SideBySide.manifest
ただし、指示どおりにマクロ定義を使用する方が、より明確で一般的です。
手順 11
SideBySide プロジェクトのフォルダーにビルド コマンド ファイル (テキスト ファイル) を作成し、それを build.cmd呼び出します。 次のコードをファイルに貼り付けます。
C# をビルドするには:
rc SideBySide.rc
csc /t:library /out:..\deployed\SideBySide.dll
/win32res:SideBySide.res Class1.cs
Visual Basic .NET をビルドするには:
rc SideBySide.rc
vbc /t:library /out:..\deployed\SideBySide.dll
/win32resource:SideBySide.res /rootnamespace:SideBySide Class1.vb
これらのコマンドは、まずプラットフォーム SDK (rc.exe) から Microsoft Windows リソース コンパイラ ツールを呼び出して、手順 10 のリソース定義スクリプトを、SideBySide.resという名前のコンパイル済みリソース ファイルにコンパイルすることです。次に、C# または Visual Basic .NET コンパイラを呼び出して、ソース コード ファイルをアセンブリにビルドし、コンパイルされたリソース ファイルを Win32 リソースとして埋め込みます。 コンパイルされたアセンブリは、
手順 12
Visual Studio 2003 コマンド プロンプトで、SideBySide プロジェクトのフォルダーに移動し、次のコマンドを実行します: build
します。
手順 13
マニフェスト ファイルを使用して、クライアントが COM 相互運用機能を使用して SideBySideClass クラスをアクティブ化できるようになったことを確認するには、\deployed\client.exe を実行し、予想される出力 "1.0.0-C#" または "1.0.0-VB.NET" を書き留めます。
トラブルシューティング
これまでに説明したように、.NET Framework ベースのコンポーネントの登録不要なアクティブ化には、サーバーまたはクライアントで特別なコードは必要ありません。 必要なのは一致するマニフェスト ファイルのペアです。そのうちの 1 つは、RT_MANIFEST型の Win32 リソースとして .NET アセンブリに埋め込まれています。
このチュートリアルの方法で、独自の登録不要の開発にアプローチすることをお勧めします。 具体的には、まず、登録済みサーバーでクライアントが動作していることを確認して、既知の状態に到達します。サーバーの登録を解除し、エラー メッセージが想定どおりであることを確認します。マニフェスト ファイルを作成して配置することで、最後に状況を解決します。 これにより、登録不要のアクティブ化に関するトラブルシューティング作業は、マニフェスト ファイルの構造とアセンブリ マニフェストの正しい埋め込みに限定されます。
登録不要の COM の問題をトラブルシューティングする場合、Windows Server 2003 のイベント ビューアーはフレンドです。 Windows XP または Windows Server 2003 で構成エラーが検出されると、通常、起動したアプリケーションのタイトルのエラー メッセージ ボックスが表示され、「アプリケーションの構成が正しくないため、このアプリケーションを起動できませんでした。 アプリケーションを再インストールすると、この問題が解決する可能性があります。このメッセージが表示されるたびに、Windows Server 2003 で問題を再現し、システム イベント ログを参照し、SideBySide ソースからイベントを検索することをお勧めします。 私がこれらのケースでXPのイベントログを見るとは思わないのは、「[パス]\[アプリケーションファイル名]に失敗したアクティベーションコンテキストを生成する」などのメッセージが必ず含まれているということです。積荷目録。 参照エラー メッセージ: 操作は正常に完了しました。これは問題の特定には役立ちません。
マニフェスト ファイルの構造に進む前に、Win32 リソースについて説明しましょう。 前述のように、windows.h では、RT_MANIFESTシンボルが値 24 として定義されます。これは、オペレーティング システムが埋め込みマニフェスト ファイルとして認識する値です。
windows.h をリソース定義スクリプト (.rc ファイル) に含め忘れた場合でも、ビルドは成功し、マニフェスト ファイルはリソースとして埋め込まれますが、正しい型は埋め込まれません。 マニフェストが正しく埋め込まれたことを確認するには、Visual Studio (SideBySide.dllファイル |開く |File...).モジュール内のリソースを示すツリー ビューが表示されます。 ルート ノードの下には、マニフェスト リソースのリソース番号を示す別のノードRT_MANIFESTという名前のノードが必要です (チュートリアルでは 1)。 この最後のノードをダブルクリックしてバイナリ ビューにデータを表示し、XML マニフェスト ファイルに似ているかどうかを簡単にサニティ チェックします。 バイナリですが、ASCII 範囲の文字は明らかです。 バイナリ データが見つからないか、正しく見つからない場合は、リソース定義スクリプト (.rc ファイル) がマニフェスト ファイルを参照していることを確認します。 RT_MANIFEST ノードのテキストが引用符で囲まれている場合は、リソース定義スクリプト (.rc ファイル) に windows.h
前述の各エラーは、Windows Server 2003 システム イベント ログで、「依存アセンブリ [名前] が見つからず、最後のエラーが参照されているアセンブリがシステムにインストールされていません」というメッセージと共に報告されます。
さまざまなマニフェスト ファイルのスキーマは、プラットフォーム SDK
登録不要の COM 意味では、アセンブリ は、アセンブリ マニフェスト ファイルの内容を使用して 1 つ以上の物理ファイルを関連付ける抽象的な概念であることを思い出します。
assemblyIdentity 要素は、アセンブリの ID を定義します。 対して。NET ベースのコンポーネントの 名 属性は、.NET アセンブリの名前とファイル名と一致する必要があります。それ以外の場合は、Windows Server 2003 システム イベント ログに次のメッセージが表示されます。"依存アセンブリ [名の値 属性] が見つかりませんでした。最後のエラーは参照先アセンブリがシステムにインストールされていません。ただし、バージョン 属性は、.NET アセンブリの AssemblyVersionや、その AssemblyFileVersionと一致する必要はありませんが、何らかの一貫性を適用することをお勧めします。
次に、アプリケーション マニフェスト ファイルに注目してみましょう。 たとえば、手順 8 を振り返ります。 アプリケーション マニフェスト
アプリケーション マニフェストの最も重要な要素は、dependentAssembly/assemblyIdentity 要素です。 この要素はアセンブリ マニフェスト内の同等の要素への参照であり、2 つは正確に
結論
登録不要の COM は、WINDOWS レジストリへの依存関係から COM コンポーネントを解放し、その結果、専用サーバーを必要としないようにそれらを使用するアプリケーションを解放するテクノロジです。 これにより、同じ COM コンポーネントの異なるバージョンに依存するアプリケーションがインフラストラクチャを共有し、.NET のバージョン管理と配置メカニズムのエコーでそれらのさまざまな COM コンポーネントのバージョンを並べて読み込むことができます。
この記事では、Visual C++ と Visual Basic 6.0 の両方で記述されたネイティブ クライアント アプリケーションによる .NET Framework ベースのコンポーネントの登録不要なアクティブ化のデモについて説明しました。 このメカニズムのしくみの一部について説明し、考えられる構成エラーとそのトラブルシューティング方法を下線で示しました。
その他の資料
- COM コンポーネントのアクティブ化の Registration-Free: チュートリアル
- 分離アプリケーションとサイド バイ サイド アセンブリの
- マニフェスト ファイル スキーマ の
- アクティブ化コンテキスト API を使用した
作成者 について
Steve White は、Microsoft UK の Premier Support for Developers チームで働くアプリケーション開発コンサルタントです。 Visual C#、Windows フォーム、ASP.NET を使用した開発のお客様をサポートしています。 彼の ブログ は、音楽、視覚化、プログラミングに関する彼の興味についての詳細情報を持っています。
Leslie Muller は、Credit Suisse First Boston のリサーチ & 開発チームの技術者です。 Leslieは、金融サービス、テクノロジースタートアップ、産業オートメーション、防衛などの環境で働く開発者および技術アーキテクトとして12年の経験を持っています。 プログラミングや研究をしていないとき、彼はスキー、アイスホッケーを楽しみ、可能な場合はアイスランドやロッキーズのような極端な環境で電動車で少し狂った事をしています。