Reg-Free COM 入門【レジストリ不要のCOM】

· · COM, Reg-Free COM, Registration-Free COM, Windows開発, レガシー技術

まず結論

  • Reg-Free COMは、COMの登録情報をレジストリではなくマニフェスト(XML)で持つやり方
  • 実行時はCoCreateInstanceの解決でアクティベーションコンテキストが先に見られる
  • COM DLL/OCXをアプリごとにprivateに持てるようになる
  • 主な利点: XCOPY配布しやすい、バージョン衝突を避けやすい、アンインストールが壊れにくい
  • ただし32bit/64bit問題は消えない。これはReg-Freeでは解決しない

なぜ普通のCOM配布は重いのか

普通のCOMはレジストリに以下を登録する:

  • CLSID(クラス識別子)
  • ProgID(人が扱いやすい名前)
  • InprocServer32(読み込むDLLのパス)
  • ThreadingModel(Apartment/Both)
  • TypeLib(型情報)

このグローバル登録が共有文化として裏目に出る:

  • ある製品のセットアップが別製品のCOM登録を上書き
  • アンインストーラーが共有COMを壊す
  • 開発機では動くのに本番機では動かない
  • 32bitと64bitの登録が噛み合わず不気味にずれる

Reg-Free COMはこの配布モデルのつらさを減らす仕組み。

仕組み

1. アプリケーションマニフェスト

アプリ側が「どのside-by-side assemblyに依存しているか」を書く。

MyApp.exe.manifest(EXEの横に置くか、リソースとして埋め込む):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" name="KomuraSoft.MyApp"
    version="1.0.0.0" processorArchitecture="amd64" />
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32"
        name="Vendor.CameraControl.Asm"
        version="1.0.0.0" processorArchitecture="amd64" />
    </dependentAssembly>
  </dependency>
</assembly>

2. コンポーネントマニフェスト

COM側が「本来レジストリに入っていた情報」を持つ。DLLにリソースとして埋め込むのが事故りにくい。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32"
    name="Vendor.CameraControl.Asm"
    version="1.0.0.0" processorArchitecture="amd64" />
  <file name="Vendor.CameraControl.dll">
    <comClass
      clsid="{01234567-89AB-CDEF-0123-456789ABCDEF}"
      progid="Vendor.CameraControl.1"
      threadingModel="Apartment" />
  </file>
</assembly>

3. アクティベーションコンテキスト

アプリがCoCreateInstanceを呼ぶと、COMランタイムはアクティブなアクティベーションコンテキストを先に見る。マニフェストに情報があればレジストリを使わずに解決できる。

注意: マニフェストに必要な情報が足りなければ、通常のレジストリベース解決へ落ちる。開発機ではたまたまレジストリ登録で助けられて動くことがある。

何がうれしいのか

  1. XCOPY配布しやすい - アプリフォルダにまとめて置ける
  2. バージョン衝突を避けやすい - アプリごとに使う版を分けられる
  3. 既存コードを大きく変えずに済む - CoCreateInstance側をほぼ触らずに導入できる
  4. 削除とロールバックが楽 - フォルダごと差し替える発想がとれる

向いている場面 / 向いていない場面

向いている

| 状況 | 相性 | |——|——| | アプリ専用のCOM DLL/OCXを同梱したい | とてもよい | | 同一PCに複数バージョンを共存させたい | とてもよい | | ベンダー部品の登録事故を避けたい | よい | | ActiveX/OCXをprivateに使いたい | よい | | 配布を軽くしつつ呼び出しは変えたくない | よい |

向いていない、または慎重に

| 状況 | コメント | |——|———| | COMをマシン全体で共有したい | Reg-Freeのうま味が薄い | | bitnessが噛み合っていない | Reg-Freeでは解決しない | | 非標準な登録に強く依存 | マニフェスト化しづらい | | 依存DLLの配布が未整理 | 別の場所でこける | | 設計時ツールがレジストリ前提 | 別の運用設計が必要 |

よくある誤解

  1. 「bitness問題が消える」 → 消えない。32bitプロセスには32bit DLLしか読み込めない
  2. 「レジストリを一切見ない」 → マニフェストに情報が足りなければレジストリへ落ちる
  3. 「型ライブラリの話も自動で片付く」 → 実行時のactivationは助けるが、設計時の参照設定は別問題
  4. 「どんなActiveX/OCXでもそのままいける」 → 追加セットアップやライセンス処理が濃いと厳しい
  5. 「.NET Frameworkと.NET 8は同じ」 → ツールチェーンが違う。.NET 5+ではEnableComHostingEnableRegFreeComを使う

.NET Framework / .NET 5+ / .NET 8の違い

系統 考え方
ネイティブCOM DLL/OCX アプリケーションマニフェスト + コンポーネントマニフェスト
.NET Framework Win32スタイルのマニフェストに加え、マネージドコンポーネント側のマニフェストも必要
.NET 5+ / .NET 8 EnableComHostingでCOM hostを作り、EnableRegFreeComでマニフェスト生成

はまりどころ

  1. 開発機では動くのに配布先で動かない → 実はレジストリ登録に助けられていたパターン。クリーン環境で検証する
  2. 「side-by-side configuration is incorrect」で起動しない → イベントログとsxstraceで追う
  3. マニフェストの対応がずれる - name/version/processorArchitectureの不一致
  4. 依存DLLを置き忘れる - Reg-Free COMはCOM登録の問題を減らすが、ネイティブ依存解決までは面倒見ない
  5. 型ライブラリの運用を後回しにする - runtimeとdesign-timeは分けて考える

検証のポイント

  • クリーン環境で確認する(COM登録のない環境)
  • sxstraceでマニフェストの解決状況を追跡する
  • bitnessと依存DLLを先に揃える
  • runtimeのactivationとdesign-timeの参照設定を分けて考える

まとめ

Reg-Free COMはCOMのアクティベーションをアプリ単位へ引き戻す仕組み

基本姿勢:

  1. これはactivationの話であると割り切る
  2. runtimeとdesign-timeの論点を分ける
  3. クリーン環境で確認する
  4. bitnessと依存DLLを先に揃える

関連する記事

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

COM/ActiveX/OCXの違いを徹底解説

COM・ActiveX・OCX の違いを土台と部品とファイルという三層で整理し、OLE との関係や IE モードを含む現代の実務での扱い方、調査の観点や残す判断の目安までコンパクトにまとめた解説記事です。

記事を読む

Excel帳票出力の方式選定ガイド

Excel 帳票出力を Windows アプリやサーバー処理にどう組み込むかを、COM 自動化、Open XML 直接生成、テンプレート差し込み、既存 VBA 活用の四方式で比較し、要件別の選び方や設計時のハマりどころまでまとめた判断表です。

記事を読む

関連トピック

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

このテーマがつながるサービス

この記事は次のサービスページにつながります。近い入口からご覧ください。

ブログ一覧に戻る