9/18/2010

WinSxSについて

どうもJudaです。
今日はVC++2005から導入されているManifestについての再配置について。
VC++2005以上でコンパイルされたプログラムは、以前存在していたDLL地獄に対応するために、ManifestによるDLLの選択という機構を取り入れました。
これによって起こっている問題は、VC++2003以前でコンパイルして、配布する際には、プライベートアセンブリや共有DLLは同名のDLLファイルが存在していれば、動作できるのです。しかし、これは正しいDLLかどうかは保障されませんでした。DLL地獄の本当のところは調べれば出てきますので、割愛します。
とりあえず手っ取り早く配布をしたい場合には、以下の手順を踏めばいけます。
・VSコマンドプロンプトでmt.exeを動作させます。
・mt.exe -inputresource: -out:を使って、埋め込まれているManifestを分離します。inputfilepathはEXEやDLLをいれて使います。
・分離されたManifestに記述されているDLLを集めます。
・DLLの場所はVisualStudio/VC/redistのところにある場合とWINDOWS/WinSxSにあります。そこから該当するものを取得します。
・WinSxSの場合には、該当するDLLとそのDLLに合致するManifestが必要になります。ManifestファイルはManifestフォルダにあります。ここから取得します。
・アプリケーションを入れるディレクトリにEXEとDLLと同じフォルダ内に、最初に取得したManifestのName属性に記述されている名前と合致するようにフォルダ名を変更して、そこにDLLとそのDLLのためのManifestを入れます。
これでたいてい動きます。それでもWinSxSのエラーが出るときには、コントロールパネル:コンピュータの管理:イベントビュアーにエラーログがでますので、そこから、問題のDLLを調べることができます。
またmt.exeを利用しなくても、VSのソリューションにExeやDLLを登録して、開くとリソースビューが開き、MT_MANIFESTとかかれている項目があります。そこにEXEなら1、DLLなら2と書かれた項目が格納されていますので、それを開きます。その際に表示された文字列が埋めこまれたManifestになります。これは最初に分離したものと同じになります。
またMSDNで記述されているようなDLLのライブラリをフォルダに入れて云々は、Manifestファイルに記述されていない際には、EXEと同じ階層に置くようになりますので、この方法から除外されます。しかしながらDLLのManifestのほうも問題がありますので、そこも要調整になります。