質問

ILMergeを使用していますか?DLL の展開を容易にするために、ILMerge を使用して複数のアセンブリをマージしますか?アセンブリを ILMerging した後、運用環境での展開/バージョン管理で問題が発生しましたか?

可能であれば、デプロイメントの手間を軽減するために ILMerge を使用することに関するアドバイスを探しています。

役に立ちましたか?

解決

私はさまざまなアプリケーションのほぼすべてに ILMerge を使用しています。私はそれをリリースビルドプロセスに直接統合しているので、最終的にはアプリケーションごとに1つのexeファイルになり、追加のDLLはありません。

ネイティブ コードを含む C++ アセンブリを ILMerge することはできません。また、WPF 用の XAML を含むアセンブリを ILMerge することもできません (少なくとも私はこれで成功したことがありません)。実行時にリソースが見つからないというメッセージが表示されます。

ILMerge 用のラッパー実行可能ファイルを作成し、マージするプロジェクトの起動 exe 名と出力 exe 名を渡します。その後、依存アセンブリが反映され、適切なコマンド ライン パラメーターを使用して ILMerge が呼び出されます。新しいアセンブリをプロジェクトに追加するときに、ビルド スクリプトを更新することを覚えておく必要がなくなり、はるかに簡単になりました。

他のヒント

導入

この投稿では、すべてを置き換える方法を示します .exe + .dll files 単一の combined .exe. 。デバッグも維持します .pdb ファイルはそのままです。

コンソールアプリの場合

ここが基本です Post Build String Visual Studio 2010 SP1 の場合、.NET 4.0 を使用します。すべての sub-.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 単一の combined .exe. 。また、デバッグ用の .pdb ファイルもそのまま維持されます。

使用するには、これを Post Build ステップ、下の Build Events C# プロジェクトのタブに移動し、最初の行のパスが次を指すように調整してください。 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 ファイルの代わりに、クライアント領域にアップロードできる 1 つのファイルがあり、さらにファイル システム構造がよりすっきりしています。

ファイルをマージした後、Visual Studio のプロジェクト リストを編集し、12 個の個別のアセンブリを削除し、単一のファイルを参照として追加する必要がありました。そうしないと、特定のアセンブリが見つからないというメッセージが表示されます。これが展開後にどのように機能するかはよくわかりませんが、試してみる価値はあるかもしれません。

これは古い質問であることは承知していますが、ILMerge を使用して依存関係の数を減らすだけでなく、ユーティリティによって使用される「内部」依存関係 (例: automapper、restsharp など) を内部化することもできます。これは、それらが完全に抽象化されており、マージされたユーティリティを使用するプロジェクトがそれらについて知る必要がないことを意味します。これにより、プロジェクト内で必要な参照が再び減り、必要に応じて同じ外部ライブラリの独自のバージョンを使用/更新できるようになります。

私たちはかなりの数のプロジェクトで ILMerge を使用しています。の Webサービスソフトウェアファクトリー, たとえば、出力として 8 つのアセンブリのようなものが生成されます。これらの DLL をすべて 1 つの DLL にマージして、サービス ホストが参照する DLL が 1 つだけになるようにします。

生活がいくらか楽になりますが、大したことではありません。

WPF の依存関係を結合する際にも同じ問題がありました。ILMerge はこれらに対処していないようです。しかし、Costur.Fody は完璧に機能し、開始までに約 5 分かかりました...とても良い経験でした。

Nuget を使用してインストールするだけです (パッケージ マネージャー コンソールで正しいデフォルト プロジェクトを選択します)。これはターゲット プロジェクトに導入され、デフォルト設定がすぐに機能しました。

「Copy Local」= true とマークされたすべての DLL をマージし、マージされた .EXE を (標準出力とともに) 生成します。このファイルのサイズは適切に圧縮されています (合計出力サイズよりも大幅に小さくなります)。

ライセンスはMITですので、必要に応じて改変・配布可能です。

https://github.com/Fody/Costura/

Windows GUI プログラム (WinForms など) の場合は、/target を使用する必要があることに注意してください。winexe スイッチ。
ターゲット:EXE スイッチはマージを作成します コンソール 応用。

同じ名前空間内にリソースを持つ DLL をマージするときに問題が発生しました。マージ プロセス中に、リソースの名前空間の 1 つが名前変更されたため、リソースを見つけることができませんでした。もしかしたら、私たちが何か間違ったことをしているだけで、まだ問題を調査しているのかもしれません。

私たちはソリューションで ILMerge の使用を開始したばかりで、他のプロジェクトで再配布および使用されており、これまでのところ非常に良好です。すべてがうまく機能しているようです。パッケージ化されたアセンブリも直接難読化しました。

MS Enterprise Library アセンブリでも同様のことを検討しています。

私が実際に感じている唯一の問題は、パッケージからの個々のアセンブリのバージョン管理です。

最近、Umbraco オープンソース CMS のリフレクション経由で呼び出されるクラスがいくつかあるアセンブリにアセンブリをイルマージしたときに問題が発生しました。

リフレクション経由で呼び出しを行うための情報は、実装されたクラスとインターフェイスのアセンブリ名と名前空間を含む DB テーブルから取得されました。問題は、DLL がマージされるとリフレクション呼び出しが失敗することでしたが、DLL が分離されている場合はすべて正常に動作しました。問題は、longeasy が抱えている問題と似ているのではないかと思います。

私は、CI ビルドの一部として ILMerge を使用し、多数のきめ細かい WCF コントラクトを 1 つのライブラリに結合し始めたところです。これは非常にうまく機能しますが、新しいマージされたライブラリは、そのコンポーネント ライブラリや、それらのコンポーネント ライブラリに依存する他のライブラリと簡単に共存できません。

新しいプロジェクトで ILMerged ライブラリと、ILMerge に指定した入力の 1 つに依存するレガシー ライブラリの両方を参照すると、ILMerged ライブラリの型をどのメソッドにも渡せないことがわかります。何らかの型マッピングを行わずに従来のライブラリを使用する (例:自動マッパーまたは手動マッピング)。これは、すべてがコンパイルされると、型がアセンブリ名で事実上修飾されるためです。

名前も衝突しますが、次を使用して修正できます。 外部エイリアス.

私のアドバイスは、マージされたアセンブリが公開している公開されているライブラリ (例:戻り値の型、メソッド/コンストラクター パラメーター、フィールド、プロパティ、ジェネリックなどを介して)、マージされたアセンブリのユーザーが同じライブラリの独立バージョンに依存せず、今後も依存しないことが確実にわかっている場合を除きます。

ILMerge の一番のベスト プラクティスは、ILMerge を使用しないことだと思われます。代わりに、使用してください スマートアセンブリ. 。その理由の 1 つは、ILMerge のベスト プラクティス 2 は、ILMerge の実​​行後に常に PEVerify を実行することです。これは、ILMerge がアセンブリを有効な実行可能ファイルに正しくマージすることを保証していないためです。

ILMerge のその他の欠点:

  • マージ時に XML コメントが削除されます (これを気にするなら、難読化ツールを使用するでしょう)
  • 対応する .pdb ファイルの作成が正しく処理されません

注目に値するもう 1 つのツールは、Mono.Cecil と Mono.Linker [2] ツールです。

[2]:http://www.mono-project.com/Linker

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top