2006 年 12 月 8 日 23 時 58 分

DllRegisterServer/DllUnregisterServer


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


さて、お膳立ては整ったので、DLL に
DllRegisterServer と DllUnregisterServer を実装しよう。

========== library.cpp ==========

// (…前略…)
// (…DllMain…)
// (…DllGetClassObject…)
// (…DllCanUnloadNow…)
// (…WriteRegistryStringValue…)
// (…DeleteRegistryValue…)
// (…RegisterIconOverlayHandler…)
// (…UnregisterIconOverlayHandler…)

STDAPI DllRegisterServer() {

    HRESULT result;

    result = RegisterIconOverlayHandler(CLSID_HardLinkIconID,
            L"Loafer Hard Link Icon Overlay Identifier", L"Apartment");
    if (FAILED(result)) return result;

    result = RegisterIconOverlayHandler(CLSID_MountPointIconID,
            L"Loafer Mount Point Icon Overlay Identifier", L"Apartment");
    if (FAILED(result)) return result;

    result = RegisterIconOverlayHandler(CLSID_FolderLinkIconID,
            L"Loafer Folder Link Icon Overlay Identifier", L"Apartment");
    if (FAILED(result)) return result;

    return S_OK;
}

STDAPI DllUnregisterServer() {

    UnregisterIconOverlayHandler(CLSID_HardLinkIconID,
            L"Loafer Hard Link Icon Overlay Identifier");

    UnregisterIconOverlayHandler(CLSID_MountPointIconID,
            L"Loafer Mount Point Icon Overlay Identifier");

    UnregisterIconOverlayHandler(CLSID_FolderLinkIconID,
            L"Loafer Folder Link Icon Overlay Identifier");

    return S_OK;
}

========== end of library.cpp ==========

DllRegisterServer/DllUnregisterServer は、
DLL の登録作業時に外部より呼び出されるため、
STDAPI(extern "C" HRESULT __stdcall)となっている。

処理の説明はもはや不要か。
クラスの登録と登録解除を行っているのである。

そして、DllRegisterServer/DllUnregisterServer を、
そのままの名前でエクスポートするため、
モジュール定義ファイルを修正する。

========== LinkIconOverlays.def ==========

EXPORTS
    DllCanUnloadNow PRIVATE
    DllGetClassObject PRIVATE
    DllRegisterServer PRIVATE
    DllUnregisterServer PRIVATE

========== end of LinkIconOverlays.def ==========

上記 4 関数が DLL よりエクスポートされるようになる。

さて、これでやっとインプロセスサーバが完成した。
後はリリース用にビルドを行うだけである。

C++ 例外処理を使っておらず、
new 以外に組み込み関数も使っていないため、
コンパイラのオプションや最適化を使えば、
軽量で高速な DLL が作成することもできるはずだ。

DllRegisterServer/DllUnregisterServer を呼び出すのは、
インストーラ・アンインストーラの仕事である。

Windows には、regsvr32 というツールが附属しており、
これを使えば直接上記関数を呼び出して、
インプロセスサーバの登録と登録解除を行うことができる。

例えば、LinkIconOverlays.dll を D:\lib に置くとすると、

    > regsvr32 D:\lib\LinkIconOverlays.dll
    > regsvr32 /u D:\lib\LinkIconOverlays.dll

上が登録、下が登録解除用のコマンドであり、
それぞれ DllRegisterServer、DllUnregisterServer を呼ぶ。

また、市販のインストーラ製品のほとんどが、
インプロセスサーバの自己登録を処理してくれるので、
インストーラを作成した配布するのはそれほど難しくない。

今回は C++ のクラスの枠組みだけを使って、
ほとんど C 言語ベースの超低水準の開発を行った。

COM の開発や利用には、C++ + MFC, C++ + ATL,
Visual Basic 4-6, .NET 系など、いくつもの方法がある。

C++ による開発は最も低水準であるため、
言語による開発サポート機能は少ない。
しかしながら、COM の裏方が見えやすいのも事実であり、
他の言語では行えないような最適化や実装も可能となる。

最近は .NET 時代に移行しつつあるが、
レジストリの HKEY_CLASSES_ROOT\CLSID 配下をみれば、
数多くの CLSID が存在することが確認できるはずだ。
今でも Windows の中心には COM が居座っているのである。



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