51

2つの問題:

1)基本的な.NETアセンブリはILMergedアセンブリに含まれていません

.NET 3.5 / VisualStudio2008から.NET4/ Visual Studio 2010にアップグレードした後、ビルド後のILMergeの使用に問題があります。ターゲットフレームワークが「.NETFramework4」に設定されているプロジェクトがいくつかあるソリューションがあります。 。次のILMergeコマンドを使用して、個々のプロジェクトDLLを単一のDLLにマージします。

if not $(ConfigurationName) == Debug
  if exist "C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe"
    "C:\Program Files (x86)\Microsoft\ILMerge\ILMerge.exe"
      /lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319"
      /lib:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies"
      /keyfile:"$(SolutionDir)$(SolutionName).snk"
      /targetplatform:v4
      /out:"$(SolutionDir)bin\development\$(SolutionName).dll"
      "$(SolutionDir)Connection\$(OutDir)Connection.dll"
      ...other project DLLs...
      /xmldocs 

.NET 4フレームワークディレクトリの場所の指定を省略した場合、ILMergeから「未解決のアセンブリ参照は許可されていません:システム」エラーが発生します。MSTestディレクトリの場所の指定を省略した場合、「未解決のアセンブリ参照は許可されていません:Microsoft.VisualStudio.QualityTools.UnitTestFramework」エラーが発生します。

上記のILMergeコマンドは機能し、DLLを生成します。ただし、別の.NET 4 C#プロジェクトでそのDLLを参照し、その中でコードを使用しようとすると、次の警告が表示されます。

プライマリ参照「MyILMergedDLL」は、バージョンよりも高いバージョン「4.0.65535.65535」を持つ.NET Frameworkアセンブリ「mscorlib、Version = 4.0、Culture = neutral、PublicKeyToken = b77a5c561934e089」に間接的に依存しているため、解決できませんでした。現在のターゲットフレームワークの「4.0.0.0」。

その後、フラグを削除して/targetplatform:v4MyILMergedDLL.dllを使用しようとすると、次のエラーが発生します。

タイプ'System.Xml.Serialization.IXmlSerializable'は、参照されていないアセンブリで定義されています。アセンブリ'System.Xml、Version = 4.0.0.0、Culture = neutral、PublicKeyToken=b77a5c561934e089'への参照を追加する必要があります。

私はそれをしなければならないようには思えません。MyILMergedDLL.dll APIを使用する人は誰でも、参照するライブラリへの参照を追加する必要はありません。どうすればこれを回避できますか?

2)マージされたアセンブリを使用する場合にのみTypeLoadException

編集:これを超えて、MyILMergedDLL.dllを使用するコンシューマープロジェクトにへの参照を追加した場合でも、System.XmlMyILMergedDLL.dllのコードを使用すると、次の例外が発生します。

System.TypeLoadException:アセンブリ'MyILMergedDLL、Version = 1.0.1.1、Culture = neutral、PublicKeyToken=...'からタイプ'System.Func`2'を読み込めませんでした。

これは私の消費者プロジェクトのコードです。を引き起こした行TypeLoadExceptionは2番目のものです:

var keys = new[] {"a", "b", "c"};
var row = new Row(keys);

Rowをスローする特定のコンストラクターTypeLoadExceptionは、のパブリッククラスで定義されておりMyILMergedDLL、個々のプロジェクトDLLを参照するときにこのコンストラクターを使用すると、正常に機能します。例外が発生するのは、ILマージされたDLLを参照するときにこのコンストラクターを使用する場合のみです。何が起こっているのかわかりません。

そのコンストラクターは次のとおりです。

public Row(IEnumerable<string> keys) : base(keys) { }

そしてbaseそれが参照しているはこのコードを持っています:

foreach (string key in keys.Where(
    key => !string.IsNullOrEmpty(key)
))
{
    _dic.Add(key, string.Empty);
}
4

6 に答える 6

48

x64の問題を解決するためのごく最近のリリースがありました。それでも問題が解決しない場合は、Mike Barnettに直接連絡してください(microsoft dot comのmbarnett)


補遺。あなたの/lib:"C:\Windows\Microsoft.NET\Framework64\v4.0.30319"オプションには非常に、非常に間違ったことがあります。.NET 4.5がリリースされた後、これは最近多くのプログラマーを悩ませています。そのディレクトリは、.NET4.0参照アセンブリに適したディレクトリではありません。その内容は4.5アセンブリで上書きされるため、.NET4.0インストールをターゲットにするために使用することはできなくなります。発生するランタイムエラーは非常に厄介で、プログラムは特定のタイプを見つけることができなくなります。通常、[Extension]属性を爆撃しますが、ICommandインターフェイスを爆撃することもあります。

これらのタイプ、および他のいくつかのタイプは、あるアセンブリから別のアセンブリに移動されました。正しい参照アセンブリを使用することは、非常に難しい要件です。使用する必要があります:

 /lib:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"

特定のマシンとターゲットフレームワークのバージョンに一致するように調整します。

于 2010-06-02T23:32:11.637 に答える
22

これは、.NET4.0を使用したVisualStudio2010SP1の「ビルド後の文字列」です。すべてのsub.dllファイルが含まれているコンソール.exeを作成しています。

"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(SolutionDir)\deploy\$(TargetFileName)" "$(TargetDir)$(TargetFileName)" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards

基本的なヒント:

  • 「\deploy」ディレクトリに注意してください。これは、出力.exeファイルが終了する場所です。
  • 「ILMerge\」ディレクトリに注意してください。ILMergeユーティリティをソリューションディレクトリにコピーしました(ILMergeのインストールを文書化することを心配せずにソースを配布できるようにしました)。

高度なヒント:

動作しないという問題がある場合は、「ビルド後」コマンドの前に「エコー」を追加してください。次に、Visual Studio(View..Output)で[出力]ウィンドウを開き、VisualStudioが実際に生成した正確なコマンドを確認します。私の特定のケースでは、正確なコマンドは次のとおりです。

"T:\PhiEngine\CSharp\ILMerge\ILMerge.exe" /out:"T:\PhiEngine\CSharp\Server Side\deploy\NfServiceDataHod.History.exe" "T:\PhiEngine\CSharp\Server Side\NfServiceDataHod\bin\Debug\NfServiceDataHod.History.exe" "T:\PhiEngine\CSharp\Server Side\NfServiceDataHod\bin\Debug\*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards

アップデート

これを「ビルド後」の手順に追加しました。これにより、すべての.exe+.dllファイルが単一の結合された.exeに置き換えられます。また、デバッグ用の.pdbファイルをそのまま保持します。

rem Create a single .exe that combines the root .exe and all subassemblies.
"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
rem Remove all subassemblies.
del *.dll
rem Remove all .pdb files (except the new, combined pdb we just created).
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).all.pdb.temp"
del *.pdb
ren "$(TargetDir)$(TargetName).all.pdb.temp" "$(TargetName).all.pdb"
rem Delete the original, non-combined .exe.
del "$(TargetDir)$(TargetName).exe"
rem Rename the combined .exe and .pdb to the original name we started with.
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb"
ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe"
exit 0
于 2011-03-23T15:58:52.837 に答える
2

その他の選択肢:

于 2011-03-23T16:08:04.990 に答える
2

次の設定ファイルを追加することもできます。

<?xml version ="1.0"?>
<configuration>
  <startup useLegacyV2RuntimeActivationPolicy="true">
    <requiredRuntime safemode="true" imageVersion="v4.0.30319" version="v4.0.30319"/>
  </startup>
</configuration>

ここから撮影

于 2012-02-26T14:38:08.107 に答える
1

Visual Studioのプロパティウィンドウで(ソリューションエクスプローラーで参照を選択した後)、PresentationCoreおよびPresentationFrameworkの参照を[ローカルのコピー=True]に設定するだけです。フレームワークパスをハードコーディングせずに問題を解決します。開発者/ビルドサーバーが64ビットか32ビットかによってパスが異なり、新しい.NET / VSバージョンがリリースされると必然的に変更されるため、このソリューションをお勧めします。

于 2013-04-26T14:38:03.120 に答える
0

.csprojのコミュニティタスクからILMergeを使用する場合:

<ILMerge InputAssemblies="@(MergeAssemblies)"
         ...
         TargetPlatformVersion="v4"
         TargetPlatformDirectory="$(ProgramFiles)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0"
/>

CIビルドエージェントのパークが混在しているため、 MSBuildチームによって推奨されているように、$(ProgramFiles)環境変数を使用して正しいパス(ドライブ+ x86 / x64フォルダー)を指定します。

于 2018-06-12T16:48:14.637 に答える