ILMerge を使用していますか? ILMerge を使用して複数のアセンブリをマージし、dll の展開を容易にしていますか? アセンブリを一緒に ILMerging した後、本番環境での展開/バージョン管理で問題が見つかりましたか?
可能であれば、ILMerge を使用して展開の摩擦を減らすことに関するアドバイスを探しています。
ILMerge を使用していますか? ILMerge を使用して複数のアセンブリをマージし、dll の展開を容易にしていますか? アセンブリを一緒に ILMerging した後、本番環境での展開/バージョン管理で問題が見つかりましたか?
可能であれば、ILMerge を使用して展開の摩擦を減らすことに関するアドバイスを探しています。
私はほぼすべてのアプリケーションで ILMerge を使用しています。私はそれをリリースビルドプロセスに統合したので、最終的にはアプリケーションごとに 1 つの exe になり、余分な dll はありません。
ネイティブ コードを含む C++ アセンブリを ILMerge することはできません。また、WPF 用の XAML を含むアセンブリを ILMerge することもできません (少なくとも、私は成功していません)。実行時に、リソースが見つからないと不平を言います。
マージするプロジェクトのスタートアップ exe 名と出力 exe 名を渡す ILMerge のラッパー実行可能ファイルを作成し、依存アセンブリを反映して、適切なコマンド ライン パラメーターで ILMerge を呼び出します。プロジェクトに新しいアセンブリを追加するときがずっと簡単になりました。ビルド スクリプトを更新することを覚えておく必要はありません。
この投稿では、すべて.exe + .dll files
を 1 つのに置き換える方法を示しますcombined .exe
。また、デバッグ.pdb
ファイルもそのまま保持されます。
Post Build String
これは、 .NET 4.0 を使用した Visual Studio 2010 SP1の基本です。すべてのサブ .dll ファイルを含むコンソール .exe を作成しています。
"$(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
AssemblyName.all.exe
出力は、すべてのサブ dll を 1 つの .exe に結合したファイル " " です。ILMerge\
ディレクトリに注意してください。ILMerge ユーティリティをソリューション ディレクトリにコピーするか (ILMerge のインストールを文書化することを気にせずにソースを配布できるようにするため)、このパスを ILMerge.exe が存在する場所を指すように変更する必要があります。動作しない問題がある場合は、 をオンにしてOutput
、 を選択しますShow output from: Build
。Visual Studio が実際に生成した正確なコマンドを確認し、エラーを確認します。
.exe + .dll files
このスクリプトは、すべてを 1 つの に置き換えますcombined .exe
。また、デバッグ用の .pdb ファイルもそのまま保持されます。
Post Build
使用するには、これを C# プロジェクトのタブの下のステップに貼り付けBuild Events
、最初の行のパスが を指すように調整してくださいILMerge.exe
。
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 project name we started with.
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb"
ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe"
exit 0
MicrosoftアプリケーションブロックでILMergeを使用します。12個の個別のDLLファイルの代わりに、クライアント領域にアップロードできる単一のファイルがあり、ファイルシステム構造は非常に優れています。
ファイルをマージした後、Visual Studioプロジェクトリストを編集し、12個の個別のアセンブリを削除し、単一のファイルを参照として追加する必要がありました。そうしないと、特定のアセンブリが見つからないと文句を言います。ただし、これが展開後にどのように機能するかはわかりませんが、試してみる価値はあります。
これは古い質問であることは承知していますが、ILMerge を使用して依存関係の数を減らすだけでなく、ユーティリティによって使用される「内部」依存関係 (オートマッパー、レストシャープなど) を内部化するためにも使用します。つまり、それらは完全に抽象化されており、マージされたユーティリティを使用するプロジェクトはそれらについて知る必要がありません。これにより、プロジェクトで必要な参照が再び減少し、必要に応じて同じ外部ライブラリの独自のバージョンを使用/更新できるようになります。
かなりの数のプロジェクトでILMergeを使用しています。たとえば、Webサービスソフトウェアファクトリーは、出力として8つのアセンブリのようなものを生成します。これらのDLLをすべて1つのDLLにマージして、サービスホストが1つのDLLを参照するだけで済むようにします。
それは人生をいくらか楽にしますが、それも大したことではありません。
WPF の依存関係を組み合わせる際にも同じ問題がありました.... ILMerge はこれらに対処していないようです。しかし、Costura.Fody は私たちにとって完璧に機能し、開始するのに約 5 分かかりました...非常に良い経験です。
Nuget を使用してインストールするだけです (パッケージ マネージャー コンソールで正しい既定のプロジェクトを選択します)。それ自体がターゲット プロジェクトに導入され、デフォルト設定がすぐに機能しました。
これは、"Copy Local" = true とマークされたすべての DLL をマージし、マージされた .EXE を (標準出力と一緒に) 生成します。このサイズは適切に圧縮されています (合計出力サイズよりもはるかに小さい)。
ライセンスは MIT なので、必要に応じて変更/配布できます。
CI ビルドの一部として ILMerge を使い始めたばかりで、多くのきめ細かい WCF コントラクトを 1 つのライブラリに結合しています。非常にうまく機能しますが、新しいマージされたライブラリは、そのコンポーネント ライブラリや、それらのコンポーネント ライブラリに依存する他のライブラリと簡単に共存できません。
新しいプロジェクトで、ILMerged ライブラリと、ILMerge に指定した入力の 1 つに依存するレガシー ライブラリの両方を参照する場合、ILMerged ライブラリから任意のメソッドに型を渡すことができないことがわかります。ある種のタイプ マッピング (オートマッパーや手動マッピングなど) を行わずに従来のライブラリを使用します。これは、すべてがコンパイルされると、型がアセンブリ名で効果的に修飾されるためです。
名前も衝突しますが、extern aliasを使用して修正できます。
私のアドバイスは、ユーザーがマージされたアセンブリは、同じライブラリの独立したバージョンに依存することはありません。
同じ名前空間にリソースを持つDLLをマージするときに問題が発生しました。マージプロセスで、リソース名前空間の1つが名前変更されたため、リソースを見つけることができませんでした。たぶん、私たちはそこで何か間違ったことをしているだけで、まだ問題を調査しています。
私たちは、他のプロジェクトで再配布および使用されているソリューションでILMergeを使い始めたばかりで、これまでのところ非常に優れています。すべてがうまくいくようです。パッケージ化されたアセンブリを直接難読化することもできました。
MSEnterpriseLibraryアセンブリでも同じことを検討しています。
私が目にする唯一の本当の問題は、パッケージからの個々のアセンブリのバージョン管理です。
私は最近、Umbraco オープンソース CMS でリフレクションを介して呼び出されていたいくつかのクラスを持っていたアセンブリにアセンブリをマージしたという問題がありました。
リフレクションを介して呼び出しを行うための情報は、実装されたクラスのアセンブリ名と名前空間とインターフェイスを持つ db テーブルから取得されました。問題は、dll がマージされたときにリフレクション コールが失敗することでしたが、dll が分離されている場合はすべて正常に機能していました。問題は longeasy が抱えている問題と似ていると思いますか?
ILMerge のベスト プラクティスの第 1 位は ILMerge を使用しないことだと思います。代わりに、SmartAssemblyを使用してください。この理由の 1 つは、#2 ILMerge のベスト プラクティスは、ILMerge を実行した後に常に PEVerify を実行することです。これは、ILMerge がアセンブリを有効な実行可能ファイルに正しくマージすることを保証しないためです。
その他の ILMerge の欠点:
注目すべきもう 1 つのツールは、Mono.Cecil と Mono.Linker [2] ツールです。
[2]: http://www.mono-project.com/Linker