3

VS 2005 以降、MS ランタイムに対して単純に dll をビルドし、それらを一緒にデプロイすることはできないことがわかりました ( http://www.ddj.com/windows/184406482 )。マニフェスト、SxS、および co に深く混乱しています。MSDN のドキュメントは、循環参照があり、非常に貧弱です。特に、私はどちらかというと Unix 派なので、これらはすべて有益ではありません。私の中心的な問題は、msvc9 または msvc8 に対して dll をリンクすることです。これらのランタイムは再配布可能ではないため、そのような dll をリンクしてデプロイする手順は何ですか? 特に、マニフェストはどのように生成されますか (mt.exe は必要ありません。コンパイラ間で移植可能なものが必要です)、マニフェストはどのように埋め込まれ、使用されますか? Side by side assembly とはどういう意味ですか?

基本的に、MS 専門用語以外の仕様はどこで見つけることができますか?

回答してくださった皆様、本当に参考になりました、ありがとうございます

4

8 に答える 8

3

すべてのアプリケーションとDLLで単純なインクルードファイルvcmanifest.hを使用してから、すべてのプロジェクトをマニフェストファイルを埋め込むように設定します。

vcmanifest.h

/*----------------------------------------------------------------------------*/

#if _MSC_VER >= 1400

/*----------------------------------------------------------------------------*/

#pragma message ( "Setting up manifest..." )

/*----------------------------------------------------------------------------*/

#ifndef _CRT_ASSEMBLY_VERSION
#include <crtassem.h>
#endif 

/*----------------------------------------------------------------------------*/

#ifdef WIN64
    #pragma message ( "processorArchitecture=amd64" )
    #define MF_PROCESSORARCHITECTURE "amd64"
#else
    #pragma message ( "processorArchitecture=x86" )
    #define MF_PROCESSORARCHITECTURE "x86"
#endif 

/*----------------------------------------------------------------------------*/

#pragma message ( "Microsoft.Windows.Common-Controls=6.0.0.0") 
#pragma comment ( linker,"/manifestdependency:\"type='win32' " \
                  "name='Microsoft.Windows.Common-Controls' " \
                  "version='6.0.0.0' " \
                  "processorArchitecture='" MF_PROCESSORARCHITECTURE "' " \
                  "publicKeyToken='6595b64144ccf1df'\"" )

/*----------------------------------------------------------------------------*/

#ifdef _DEBUG
    #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT=" _CRT_ASSEMBLY_VERSION ) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
            "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT' "         \
            "version='" _CRT_ASSEMBLY_VERSION "' "                          \
            "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
            "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#else
    #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT=" _CRT_ASSEMBLY_VERSION ) 
    #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
            "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' "              \
            "version='" _CRT_ASSEMBLY_VERSION "' "                          \
            "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
            "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
#endif

/*----------------------------------------------------------------------------*/

#ifdef _MFC_ASSEMBLY_VERSION
    #ifdef _DEBUG
        #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION ) 
        #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
                "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              \
                "version='" _MFC_ASSEMBLY_VERSION "' "                          \
                "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
                "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
    #else
        #pragma message ( __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC=" _CRT_ASSEMBLY_VERSION ) 
        #pragma comment(linker,"/manifestdependency:\"type='win32' "            \
                "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".MFC' "              \
                "version='" _MFC_ASSEMBLY_VERSION "' "                          \
                "processorArchitecture='" MF_PROCESSORARCHITECTURE "' "         \
                "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")
    #endif
#endif /* _MFC_ASSEMBLY_VERSION */

/*----------------------------------------------------------------------------*/

#endif /* _MSC_VER */

/*----------------------------------------------------------------------------*/
于 2008-09-22T03:20:49.027 に答える
3

最も簡単な方法: VS2005 のデフォルト インストールを想定すると、次のようなパスが作成されます。

C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT

行って、この redist フォルダー内のファイルを取得し、.manifest と msvcr80.dll (少なくとも) をアプリケーションの .exe フォルダーに配置します。これらのファイルは、インストールのルートに存在し、exe およびそれらにリンクされているすべての dll を有効にし、マージ モジュール、MSI、またはランタイムがインストールされていないことを実際にジャストインタイムで検出する必要なく、問題なく動作できるようにする必要があります。

于 2008-10-22T14:21:56.147 に答える
2

さて、私はこれらの問題のいくつかに遭遇したので、おそらく私のコメントのいくつかが役立つでしょう.

  1. マニフェストは xml ファイルです。VS はコンパイル時に作成できますが、もう 1 つの解決策は、リソース ファイル (.rc) を生成し、VS に含まれているリソース コンパイラ (rc.exe) を使用してコンパイル済みリソース ファイル (.res) にコンパイルすることです。 . ツール メニューから VS コマンドラインを実行すると、rc がパスに追加され、さまざまな環境変数が正しく設定されます。次に、リソースをコンパイルします。結果の .res ファイルは、他のコンパイラで使用できます。
  2. マニフェスト xml ファイルのサイズが 4 で割り切れることを確認してください。必要に応じて、これを実現するために中間に空白を追加してください。xml の開始タグの前または xml の終了タグの後に文字を入れないようにしてください。私は時々これに問題がありました。ステップ 2 を誤って実行すると、サイド バイ サイド構成エラーが発生することが予想されます。リソース エディター (devenv.exe など) で exe を開き、マニフェスト リソースを調べることで、それが間違いであるかどうかを確認できます。ビルドされたファイルを開くだけで、正しいマニフェストの例を確認することもできますが、dll と exe では、リソースに指定する ID がわずかに異なることに注意してください。

これが正しく機能することを確認するために、Vista でテストすることをお勧めします。

于 2008-09-21T04:46:53.477 に答える
2

これは、 VC++ の SxS crt 決定の背後にある合理性を説明するブログ エントリです。これには、crt を静的にリンクすることがいかに悪いことであるか、およびなぜそうするべきではないかの説明が含まれています。

これは、 crt を静的にリンクする方法に関するドキュメントです。

于 2008-09-21T05:29:23.500 に答える
1

それらは再配布可能で、msvs ディレクトリ内に再配布可能なパッケージがあります。

選択したランタイムでビルドし、対応するパッケージをインストーラーに追加してください。気にする必要はありません。動作します。違いは、現在は別の場所にインストールされていることです (ただし、アプリがライブラリを探す場所でもあります)。

それ以外の場合は、MSDN または基本的に Windows C++ プログラミングに関するあまり古くない本。

于 2008-09-21T04:49:59.447 に答える
0

答えてくれてありがとう。展開自体については、次の 3 つのオプションが表示されます。

  • .msi マージ ディレクティブを使用します。
  • 再配布可能な VS パッケージを使用して、独自のインストーラーの前に実行する
  • 自分のアプリケーションに沿って再配布可能なファイルをコピーします。しかし、この場合、ファイルシステム階層でそれを参照するにはどうすればよいですか (たとえば、bar/foo1/foo1.dll と bar/foo2/foo2.dll は bar/ の msvcr90.dll を参照します)。私は、明白で醜いことに加えて、「それに依存するdllがあるすべてのディレクトリにdllをコピーする」ことを意味します。
于 2008-09-21T08:36:14.957 に答える
0

MSI の「InstallFinalize」アクションの前に開始したいサービスまたは実行したいプログラムがある場合、Vista および Windows Server 2008 で VC++8 SP1/9 CRT をマージ モジュールとして使用することはできません。

これは、DLL が「InstallFinalize」アクションで WinSXS にインストールされるためです。

ただし、MSI の「ServiceStart」アクションはこの前に来ます。

したがって、ブートストラップ " http://www.davidguyer.us/bmg/publish.htm "を使用してください。

または、インストーラー 4.5 でのインストーラー チェーンの使用を検討してください。しかし、これは4.5をインストールするにはブートストラップが必要であることを意味するので、少し無意味に思えます..

于 2008-10-16T16:19:14.447 に答える