4

ほとんどがC#で記述された非常に大規模なプロジェクトがあり、C ++で記述された、小さいながらも重要なコンポーネントがいくつかあります。最低限必要なバージョンとして、.NET2.0のRTMをターゲットにしています。これまでのところ、この要件を満たすために、ビルドボックスに.NET 2.0のRTMのみが含まれていることを確認し、C++ピースがそのバージョンに対してリンクするようにしました。

更新:問題の原因となっているC ++アセンブリは、管理対象プロセスにロードされている混合モードのC++アセンブリです。

残念ながら、confikerが4月1日に何かをするように設定されたとき、私たちの企業ITはすべてにパッチを適用して最新の状態にするために大いに力を入れ、その結果、3.5SP1までのすべてがビルドボックスにインストールされました。以前に発生したすべてのアンインストールを試みましたが、その特定のボックスで構築されたものには.NET 2.0 SP1が必要なため、最小要件を満たすことができません。

問題のあるバージョンをアンインストールするだけではアンインストールできないという点でボックスがアンインストールされているように見えるので、アセンブリをビルドして、.NET 2.0(v2.0.50727.42)のRTMを使用するように明示的に指示する方法はありますか?マニフェストの使用について言及しているページを見たことがありますが、実際に適切なマニフェストを実装してアセンブリに組み込む方法がわかりません。私の専門知識は管理された世界にあるので、これには少し戸惑っています。

これらのアセンブリを.NET2.0RTM SxSアセンブリをターゲットにする方法を誰かが説明できますか?

ありがとう!

4

6 に答える 6

8

クリストファーの回答とコードサンプル(ありがとう、クリストファー!)は、よりエレガントなソリューションの一部であると確信していますが、私たちはこれを実現するために銃を突きつけられ、非常に似ているが異なるソリューションを見つけました。

最初のステップは、アセンブリのマニフェストを作成することです。

<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC80.DebugCRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type='win32' name='Microsoft.VC80.CRT' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
    </dependentAssembly>
  </dependency>
</assembly>

次に、[構成プロパティ]->[リンカー]->[マニフェストファイル]で[マニフェストの生成]オプションを[いいえ]に設定し、[構成プロパティ]->[マニフェストツール]->[入力と出力]で[埋め込みマニフェスト]オプションを[いいえ]に設定する必要があります。 。

最後に、新しいマニフェストをアセンブリに取り込むには、プロジェクトのビルド後の手順に次のコマンドを追加します。

mt.exe /manifest "$(ProjectDir)cppassembly.dll.manifest" /outputresource:"$(TargetDir)\cppassembly.dll";#2 -out:"$(TargetDir)\cppassembly.dll.manifest"

ビルドしたら、Visual Studioでdllを開いて、RT_MANIFESTの下のマニフェストを表示し、マニフェストがあることを確認できます。

Christopherのコードをstdafx.hに配置すると、追加の依存関係として追加されました...マニフェストはまだv8.0.50727.762を探していました。生成されたマニフェストは次のようになりました。

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.VC80.CRT" version="8.0.50727.762" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
    </dependentAssembly>
  </dependency>
</assembly>

既存の依存関係を削除またはクリアする別のスイッチを追跡できませんでした。私はクリストファーのアプローチがビルド後のステップよりも好きですが、今のところこれはうまくいきます。誰かが既存の依存関係をクリアする方法について追加の入力がある場合は、それは素晴らしいことです。

ありがとう!

于 2009-07-07T15:40:48.420 に答える
3

はい。プロジェクトのプロパティには、実行時間を示すページがあります。使用可能なすべてのランタイムを一覧表示するドロップダウンがあります。自分に合ったものを選んでください。(VS 2008の場合:プロジェクト->プロパティ、[コンパイル]タブ、[コンパイラの詳細設定]ボタン-> [ターゲットフレームワーク]を右クリックします)

私たちは今これを行っています。VS 2008に移行したいのですが、段階的に移行しています。そのため、現在VS 2008ソリューションがありますが、すべてのプロジェクトは引き続き.Net2.0を対象としています。したがって、コンパイルしてデプロイする場合、テストボックスに.Net3.5のものをインストールする必要はありません。

アップデート:

ネイティブプログラムを強制的に特定のバージョンの.dllにリンクするには、次のようなものを使用することをお勧めします。

#pragma message ("Explicit link to generate a manifest entry for MFC.")

#if defined (_DEBUG)

#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.VC80.DebugMFC' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b'\"")

#else

#pragma comment(linker, "\"/manifestdependency:type='win32' name='Microsoft.VC80.MFC' version='8.0.50608.0' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b'\"")

#endif

ただし、MFCの代わりに、.Net.DLLの正しい値を見つける必要があります。

.Net2.0SP1と.Net2.0を同じボックスに入れることはできないと考えるのが妥当です。したがって、これをそのボックスで機能させることは、本当に、本当に苦痛になるでしょう。パッチが適用されていない古い.Netフレームワークをインストールできる新しいビルドVMを起動することをお勧めします(もう手に入れることができる場合)。

それ以外の場合は、すべてのビルド時ファイルを現在のボックスにコピーしてから、ビルドタイプに基づいてインクルードパスとライブラリパスを調整する必要があります。おそらく、これは価値があるよりもはるかに大きな頭痛の種です。

于 2009-07-06T15:34:03.700 に答える
3

ジョンは、同じ問題を解決するために私を本当に正しい道に導いてくれました。古い VS2005 C++ (非 CLR) プロジェクトを少し変更しています。私の開発マシンにはすべての更新が含まれているため、VS2005 は MFC80 および MSVCx80 DLL の最新バージョンへの参照を作成していましたが、これらのバージョンが利用できず、それらのマシンを更新するオプションがないため、実行可能ファイルはターゲット マシンで実行されませんでした。 . そのため、実行可能ファイルに埋め込まれているマニフェストで assmelby の依存関係を制御する必要があります。これは、ジョンが取り組んでいるのと同じ問題のようです。彼の追加情報から始めて、これが私にとってうまくいきました。

ProjectDirで、適切なアセンブリ参照情報を使用して、program.exe.debug.manifestおよびprogram.exe.release.manifestファイルを作成します。これらをプロジェクトまたはリンカーに追加しないでください。すべてのビルドに両方を含めるようにしてください。次に、プロジェクトのプロパティを次のように設定します。

リンカ -> マニフェスト ファイル オプション

  • マニフェストの生成: いいえ
  • マニフェスト ファイル: 空白
  • 追加のマニフェスト依存関係: 空白
  • 分離を許可: はい

マニフェスト ツール -> 入力および出力オプション

  • 追加のマニフェスト ファイル: $(ProjectDir)$(TargetFileName).$(ConfigurationName).manifest
  • 入力リソース マニフェスト: 空白
  • 埋め込みマニフェスト: はい
  • 出力マニフェスト ファイル: (自動入力)
  • マニフェスト リソース ファイル: (自動的に入力されます)
  • カタログ ファイルの生成: いいえ
  • 依存関係情報ファイル: $(IntDir)\mt.dep (自動入力)

私のテストでは、これは他のマニフェスト ファイルを生成せず、手動でコーディングしたマニフェスト情報を RT_MANIFTEST リソース #1 として EXE に埋め込むようです。

マニフェスト ツールのオプションで、「<strong>出力マニフェスト ファイル」と「<strong>マニフェスト リソース ファイル」は、クリアしても自動的に入力されました。

これにより、アセンブリの依存関係を制御し、実行可能ファイルをターゲット マシンで実行できるようになります。追加の利点は、他の目的で使用されているビルド後のステップを使用する必要がないことです。リンカーとマニフェスト ツールのオプションを操作することで、同じ結果を得ることができます。

申し訳ありませんが、スクリーン ショットをアップロードできませんでしたが、私は新しいユーザーであり、画像はまだ許可されていません。

于 2011-07-08T21:42:28.607 に答える
1

ジョンの答えは私たちにとってうまくいきます。Visual C++ 2005 では、コンパイラは MFC と CRT の 762 バージョンと 4053 バージョンの両方を含むマニフェストを生成します。マニフェストから 4053 バージョンを削除し、上記の手動の手順に進みました。(内部コードは実際には 4053 を取得しますが、これは 762 を超えるセキュリティ修正として認識されていますが、仕様が必要であるか、リンクが失敗するだけです。)

Ted のブログ (tedwvc.wordpress.com) の投稿からヒントが得られましたが、彼の解決策はうまくいきませんでした。ここでのこのアプローチは機能します。

于 2009-09-10T19:16:04.130 に答える
1

これがハックであることはわかっていますが、マニフェストを外部で生成し、メモ帳で変更することに頼りました。ピンチで、それは私のためにトリックを行いました. 私の場合、.762 CRT を指す VC++ 2005 アプリを探していました。

幸運を!テリー

于 2009-08-20T07:26:59.797 に答える
0

あなたが欲しいと思いCorBindToRuntimeます。これにより、C++ がロードする CLR のバージョンを指定できます。

于 2009-07-06T15:47:32.073 に答える