検索 
2010年9月5日 ..:: ブログ ::..   ログイン


 COM DLL をレジストリに登録しないで使用する方法 (COM DLL の Side-by-Side 実行)

chack のブログProgramming
   
By : Akira INOUE 2007/10/02 17:15

Windows XP 以降では、COM DLL をレジストリに登録 (regsvr32) しなくても、アプリケーションで使用できる仕組みが用意されています。

【Windows XP で分離アプリケーションと Side-by-Side アセンブリをビルドし、サービスを提供する方法】
http://www.microsoft.com/japan/msdn/windows/windowsxp/sidexsidewinxp.aspx

などに詳細が記述されていますが、ちょっと難しく書かれていて読んでもいまいちピンときません。

先日、知人に聞かれたのを機に、改めて試してみました。

上記のドキュメントで、Side-by-Side (SxS) アセンブリという言葉が出てきますが、簡単に言ってしまえばこれまでの Win32 ネイティブな DLL のことです。ドキュメント中にも Win32 アセンブリという記述があります。
ただ、Win32 DLL と言っても、複数の DLL をひとまとめにして Side-by-Side アセンブリを構成する場合もありますし、それらの DLL が COM コンポーネントとして作成されている場合もあります。

ここでは、シンプルに以下の構成で COM DLL を サイドバイサイド実行するサンプルを紹介します。

実行ファイル : SampleApp.exe
COM DLL : SampleCom.dll

この場合、通常は

C:\>regsvr32 SampleCom.dll

で、レジストリに登録すれば SampleApp.exe や、その他のアプリケーションで SampleCom.dll が使用できます。

これを、SampleApp.exe と SampleCom.dll を同じフォルダに配置して、SampleCom.dll をレジストリに登録しないで SampleApp.exe から使用するには、以下の作業をおこなうことになります。

  1. アセンブリ名を決める
  2. アプリケーションマニフェストを作成する
  3. アセンブリマニフェストを作成する

なお、実行ファイルと DLL を同じフォルダに配置して使用する場合の Side-by-Side (Win32) アセンブリをプライベートアセンブリといいます。一方、Side-by-Side アセンブリ キャッシュ(Windows フォルダ内の WinSxS フォルダ)に配置する方法もあり、この場合は共有アセンブリといいます。
ここではプライベートアセンブリとして COM DLL を使用します。共有アセンブリとして WinSxS フォルダに配置して使用する方法は上記のドキュメントなどを参考にしてください。

 

1. アセンブリ名を決める

アセンブリ名は Organization.Division.Name の形式が推奨されています。
ここでは、

BitWiz.Samples.SampleCom

とします。

2. アプリケーションマニフェストを作成する

マニフェストファイルは、拡張子が .manifest の XML ファイルです。
アプリケーションマニフェストは、実行ファイル名に .manifest を付加したファイル名とします。

ここでは、実行ファイル名が SampleApp.exe ですから、アプリケーションマニフェストファイル名は

SampleApp.exe.manifest

となります。

このアプリケーションマニフェストに、アプリケーションの情報と Side-by-Side アセンブリとの依存関係を記述します。BitWiz.Samples.SampleCom アセンブリとの依存関係を記述したマニフェストファイルを以下に示します。

【SampleApp.exe.manifest】

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity
    version="1.0.0.1"
    processorArchitecture="x86"
    name="BitWiz.Samples.SampleApp"
    type="win32"
/>

<description>アプリケーションの説明をここに記述します。</description>

<dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="BitWiz.Samples.SampleCom"
            version="1.0.0.1"
            processorArchitecture="x86"
        />
    </dependentAssembly>
</dependency>

</assembly>

3. アセンブリマニフェストを作成する

アセンブリ名を BitWiz.Samples.SampleCom としましたので、

BitWiz.Samples.SampleCom.manifest

というファイル名のアセンブリマニフェストを作成します。
このマニフェストには、アセンブリを構成するファイル(DLL)の情報を記述します。
COM DLL の場合は comClass 要素を使って、clsid などの COM 登録情報を記述します。

SampleCom.dll が次に示す情報を持つ場合のアセンブリマニフェストを以下に示します。

クラス名:SampleCom Class
GUID:{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
スレッディングモデル:apartment
プログラムID:BitWiz.SampleCom
タイプライブラリGUID:{ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ}

【BitWiz.Samples.SampleCom.manifest】

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">

<assemblyIdentity
    version="1.0.0.1"
    processorArchitecture="x86"
    name="BitWiz.Samples.SampleCom"
    type="win32"
/>

<file name="SampleCom.dll">
    <comClass description="SampleCom Class"
        clsid="{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}"
        threadingModel="apartment"
        progid="BitWiz.SampleCom"
        tlbid="{ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ}"
    />
</file>

</assembly>

なお、もし COM DLL のソースコードなどがなく GUID などの情報がわからない場合は、一度 regsvr32 でレジストリに登録し、レジストリを直接参照するなどして入手する必要があります。

 

以上の2つのマニフェストファイルを記述したら、以下の4つのファイル

├ SampleApp.exe
├ SampleApp.exe.manifest
├ SampleCom.dll
└ BitWiz.Samples.SampleCom.manifest

を同一フォルダに配置し、SampleApp.exe を実行してみましょう。
問題がなければ、SampleCom.dll をレジストリに登録しなくても使用できることが確認できると思います。

なお参考までに、アセンブリ名と同じフォルダを作成して以下のように配置することもできます。

├ SampleApp.exe
├ SampleApp.exe.manifest
└ BitWiz.Samples.SampleCom  (フォルダ)
   ├ SampleCom.dll
   └ BitWiz.Samples.SampleCom.manifest

◇◇◇

以上のようにして Windows XP 以降では、適切なマニフェストファイルを用意し、実行ファイルと共に COM DLL をコピーするだけで他のアプリケーションに依存させずに COM コンポーネントを使用することができます。

 

固定リンク |  トラックバック

コメント(8)  
Re: COM DLL をレジストリに登録しないで使用する方法 (COM DLL の Side-by-Side 実行)    投稿者:RF 投稿日: 2007/11/14 10:38
現在WindowsVistaでDLLHELLを回避するため、manifestについて調べております。
Microsoftのページを見てもよくわからなかったので、わかりやすく書かれていて大変参考になりました。

サンプルを参考にXP端末で実行したところ、System32のDLLを見ずにローカルのDLLを見るようになったのですが、Vista端末で同じmanifestファイルを使用するとSystem32を見に行ってしまいました。

Vistaでは他に何か設定が必要なのでしょうか?
ご存知でしたらご教示願います。

以下,作成したmanifestです。
comClassのtlbidについてはレジストリエディタのどこを参照するべきかわからず、設定しておりません。

【YP015000.exe.manifest】


version="1.0.0.0"
processorArchitecture="x86"
name="APPLICATION"
type="win32"
/>
アプリケーションの説明


type="win32"
name="Microsoft.Windows.SidebySide.TEST"
version="1.0.0.0"
processorArchitecture="x86"/>




【Microsoft.Windows.SidebySide.TEST.manifest】


name="Microsoft.Windows.SidebySide.TEST"
version="1.0.0.0"
processorArchitecture="x86"/>

description="CrDraw.ocx Test"
clsid="{A37A80A8-3F34-11D2-912B-00C0DF49BE5E}"
progid="CoReports.CrDraw.1"
/>


description="CrCore.dll Test"
clsid="{77748DE9-7AAF-11D2-91B5-00C0DF49BE5E}"
progid="CoReportsCore.CrPrinters.1"
/>




Re: COM DLL をレジストリに登録しないで使用する方法 (COM DLL の Side-by-Side 実行)    投稿者:RF 投稿日: 2007/11/14 10:54
先ほどのコメントのソース部分が切れてしまいましたが、基本的にはサンプルと同じに作成いたしました。

Re: COM DLL をレジストリに登録しないで使用する方法 (COM DLL の Side-by-Side 実行)    投稿者:RF 投稿日: 2007/11/14 12:43
先ほどのコメントのソース部分が切れてしまいましたが、基本的にはサンプルと同じに作成いたしました。

Re: COM DLL をレジストリに登録しないで使用する方法 (COM DLL の Side-by-Side 実行)    投稿者:Akira INOUE 投稿日: 2007/11/14 14:45
RF さん、コメントありがとうございます。
Vista で動作しないとのことですが、わたしの環境では Vista で動作しています。
YP015000.exe は VS2005 で作成された Win32 (MFC?)アプリケーションでしょうか?
そうだとすると、デフォルトでアプリケーションマニフェストが exe に埋め込まれた状態となります。その場合、外部に置いたアプリケーションマニフェストは読み込まれません。
埋め込みのアプリケーションマニフェストに関しては
http://bitwiz.jp/tabid/56/EntryID/18/Default.aspx
あたりを参考にしてください。記事としては別なものですが、少し参考になるかと思います。
もし、埋め込みマニフェストがある状態なら、それを削除するか、もしくは外部に置いているアプリケーションマニフェストファイルを「追加のマニフェストファイル」として、exe に埋め込んでみてください。

そのほかの原因はちょっと不明ですねぇ。tlbid は関係ないと思います。

Re: COM DLL をレジストリに登録しないで使用する方法 (COM DLL の Side-by-Side 実行)    投稿者:RF 投稿日: 2007/11/14 17:57
早速のご回答ありがとうございます。

使用した端末ですが、スタンドアローンでテスト端末として使用していたため、WindowsUpdateを実施したところ動くようになりました。

Vistaの当初のバグのようですね。
ありがとうございました。

ちなみに、YP015000.exe は VS2005 より前に作成したものなので、マニフェストが埋め込まれていないです。

Re: COM DLL をレジストリに登録しないで使用する方法 (COM DLL の Side-by-Side 実行)    投稿者:シャノン 投稿日: 2008/02/13 15:00
マニフェストを埋め込む場合、アセンブリ名と、ファイル名から拡張子を除いた部分が一致する必要があります。

何か方法はありませんか?HKEY_LOCAL_MACHINE    投稿者:kaskas 投稿日: 2008/04/18 16:04
いかの内容を解決する方法はありますでしょうか。

あるインストーラがあります。
それはDLLファイル(VideoCodec)をシステムフォルダにコピーし、レジストリのHKEY_CLASSES_ROOT(avifileキー)とHKEY_LOCAL_MACHINE(Drivers32、dirvers.descキー)に書き込みをします。

Admin権限があれば問題ないのですが、制限ユーザーではインストールできません。

COM DLLではありませんが、マニフェストファイルの様に登録して使うことはできないでしょうか。
また、こうすればできるという方法があれば教えていただけないでしょうか。

何か方法はありませんか?    投稿者:kaskas 投稿日: 2008/04/18 16:06
いかの内容を解決する方法はありますでしょうか。

あるインストーラがあります。
それはDLLファイル(VideoCodec)をシステムフォルダにコピーし、レジストリのHKEY_CLASSES_ROOT(avifileキー)とHKEY_LOCAL_MACHINE(Drivers32、dirvers.descキー)に書き込みをします。

Admin権限があれば問題ないのですが、制限ユーザーではインストールできません。

COM DLLではありませんが、マニフェストファイルの様に登録して使うことはできないでしょうか。
また、こうすればできるという方法があれば教えていただけないでしょうか。


MCAD


techbank.jp


Copyright © 2005-2008 by BitWiz   使用条件  プライバシー