自己登録
コンポーネント ソフトウェアが市場として成長し続けるにつれ、オンライン サービスから新しいコンポーネントをダウンロードしたり、友人からフロッピー ディスクに入ったコンポーネントをもらったりするなど、ユーザーが新しいソフトウェア コンポーネントを単一の DLL または EXE モジュールとして入手するケースがますます増えていくでしょう。 このような場合、ユーザーに長いインストール手順やセットアップ プログラムを要求するのは現実的ではありません。 IClassFactory2 によって処理されるライセンスの問題に加えて、インストール手順では通常、COM および OLE コンテキストでコンポーネントを適切に実行するために必要なレジストリ エントリが作成されます。
自己登録は、サーバー モジュールが独自のレジストリ操作 (登録と登録解除の両方) をモジュール自体にパッケージ化できる標準的な手段です。 IClassFactory2 で処理されるライセンスと共に使用すると、サーバーは完全に自己完結型のモジュールになり、外部インストール プログラムや.reg ファイルは必要ありません。
次に示すように、自己登録モジュール DLL または EXE は、まず、バージョン情報リソースの StringFileInfo セクションに「OleSelfRegister」文字列を含める必要があります。
VS_VERSION_INFO VERSIONINFO
...
BEGIN
BLOCK "StringFileInfo"
BEGIN
#ifdef UNICODE
BLOCK "040904B0" // Lang=US English, CharSet=Unicode
#else
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
#endif
BEGIN
...
VALUE "OLESelfRegister", "\0"
END
...
END
...
END
このデータの存在により、この新しいコンポーネントを統合したいアプリケーションなどの関係者は、最初に DLL または EXE をロードしなくても、サーバーが自己登録をサポートしているかどうかを判断できます。
サーバーが DLL モジュールにパッケージ化されている場合、DLL は DllRegisterServer 関数と DllUnregisterServer 関数をエクスポートする必要があります。 サーバー自体 (つまり、すべての CLSID とタイプ ライブラリ ID) を登録するようにサーバーに指示するすべてのアプリケーションは、GetProcAddress 関数を使用して DllRegisterServer へのポインターを取得できます。 DllRegisterServer 内で、DLL は必要なすべてのレジストリ エントリを作成し、すべての InprocServer32 エントリまたは InprocHandler32 エントリの DLL への正しいパスを格納します。
アプリケーションがシステムからコンポーネントを削除する場合は、DllUnregisterServer を呼び出してそのコンポーネントの登録を解除する必要があります。 この呼び出しの中で、サーバーは DllRegisterServer で以前に作成したエントリを正確に削除します。 他のソフトウェアが TreatAs キーなどの追加のエントリを格納している可能性があるため、サーバーはクラスのすべてのエントリをむやみに削除しないでください。
サーバーが EXE モジュールにパッケージ化されている場合、サーバーを登録するアプリケーションは、コマンド ライン引数 /RegServer または -RegServer (大文字と小文字を区別しない) を使用して EXE サーバーを起動します。 アプリケーションがサーバーの登録を解除する場合は、コマンド ライン引数 /UnregServer または -UnregServer を使用して EXE を起動します。 自己登録 EXE は、これらのコマンド ライン引数を検出し、DllRegisterServer および DllUnregisterServer 内の DLL と同じ操作をそれぞれ呼び出し、InprocServer32 または InprocHandler32 の代わりに LocalServer32 にモジュール パスを登録します。
サーバーは、レジストリ内のそれぞれの InprocServer32、InprocHandler32、および LocalServer32 キーの DLL または EXE モジュールのインストール場所への完全なパスを登録する必要があります。 モジュール パスは、GetModuleFileName 関数を使用して簡単に取得できます。
関連トピック