システム

【C#】ILMergeとCosturaでDLLを1ファイルにまとめる方法と注意点

複数DLLを1ファイルにまとめたいなら、.NET FrameworkではILMerge、.NET Core以降ではSingle-file publishILRepack、汎用的に使いやすいのはCostura.Fodyです。

配布をシンプルにでき依存忘れを防げますが、ファイルサイズ増加とデバッグ難度が上がる点に注意してください。

目次から探す
  1. アセンブリ統合のメリットとリスク
  2. ツール選択の全体像
  3. ILMergeの使い方
  4. ILMerge高度な設定
  5. Costura.Fodyの使い方
  6. Costura.Fodyのカスタマイズ
  7. ILMergeとCosturaの比較
  8. マージ後のテストとデバッグ
  9. セキュリティ・ライセンスの注意点
  10. デプロイメントへの組み込み
  11. トラブルシューティング
  12. まとめ

アセンブリ統合のメリットとリスク

C#で開発したアプリケーションを配布する際、複数のDLLファイルを1つの実行可能ファイル(.exe)にまとめることはよく行われます。

ここでは、アセンブリ統合のメリットとリスクについて詳しく解説します。

配布が楽になる理由

複数のDLLを1つの実行ファイルにまとめる最大のメリットは、配布が非常に楽になることです。

通常、C#のアプリケーションはメインの実行ファイル(.exe)と複数の依存DLLファイルで構成されます。

これらのDLLをすべて正しい場所に配置しなければ、アプリケーションは正常に動作しません。

アセンブリ統合を行うと、依存DLLが実行ファイルに埋め込まれるため、配布時にDLLファイルを別途用意する必要がなくなります。

ユーザーは単一のファイルを受け取るだけで済み、インストールや展開の手間が減ります。

特に、USBメモリやネットワーク経由での配布、または単純にファイルをコピーして使うシナリオで効果的です。

また、配布物が1ファイルにまとまることで、誤ってDLLを紛失したり、バージョン違いのDLLが混在したりするリスクも減ります。

これにより、トラブルシューティングの手間も軽減されます。

依存DLL忘れを防ぐ効果

依存DLLの配置ミスは、C#アプリケーションの配布でよくある問題の一つです。

たとえば、開発者がDLLをプロジェクトに追加したものの、配布時にそのDLLを含め忘れてしまうことがあります。

結果として、実行時に「ファイルが見つからない」や「アセンブリがロードできない」といったエラーが発生します。

アセンブリ統合を使うと、依存DLLが実行ファイルに埋め込まれるため、こうしたDLL忘れの問題を根本的に防げます。

ユーザーは単一のファイルを実行するだけで済み、DLLの有無を気にする必要がなくなります。

また、DLLのバージョン管理も容易になります。

複数のDLLを別々に配布すると、異なるバージョンのDLLが混在するリスクがありますが、統合後は一つのファイルにまとめられているため、バージョンの不整合を防げます。

ファイルサイズ増加とパフォーマンスへの影響

アセンブリ統合を行うと、実行ファイルのサイズは当然ながら大きくなります。

複数のDLLを1つにまとめるため、元の実行ファイルに加えてDLLのバイナリがすべて含まれるからです。

ファイルサイズの増加は、配布時のダウンロード時間やストレージの消費に影響します。

特に、ネットワーク経由で配布する場合は、ファイルサイズが大きいとユーザーの待ち時間が長くなる可能性があります。

パフォーマンス面では、起動時の読み込み処理に影響が出ることがあります。

たとえば、Costura.FodyのようにDLLを埋め込んで実行時にメモリ上で展開する方式では、起動時に展開処理が発生するため、起動時間がわずかに遅くなることがあります。

一方、ILMergeのように複数のアセンブリを1つのアセンブリに結合する方式では、起動時の展開処理は不要ですが、ファイルサイズの増加は避けられません。

このように、ファイルサイズの増加と起動パフォーマンスの低下はトレードオフの関係にあるため、用途や配布環境に応じて適切に選択する必要があります。

デバッグ難易度が上がるケース

アセンブリ統合を行うと、デバッグが難しくなる場合があります。

特にILMergeで複数のアセンブリを1つにまとめた場合、元のDLLごとの分離がなくなるため、例外発生時のスタックトレースがわかりにくくなることがあります。

また、統合後の実行ファイルに対応したPDB(デバッグシンボル)ファイルを用意しないと、ブレークポイントが正しく機能しなかったり、ソースコードの対応が取れなくなったりします。

ILMergeはPDBファイルの統合もサポートしていますが、設定が複雑になることがあります。

Costura.Fodyの場合は、DLLを埋め込んで実行時に展開するため、元のDLLのデバッグ情報は保持されますが、展開タイミングやAssemblyResolveイベントの処理が絡むため、デバッグ時にアセンブリのロード順序や解決に関する問題が発生しやすくなります。

開発中は統合を行わず、デバッグが完了してから統合する運用が一般的です。

統合後のデバッグが必要な場合は、PDBファイルの管理やデバッグ設定を慎重に行うことが重要です。

ツール選択の全体像

.NET Framework向けの候補

.NET Framework環境で複数のDLLを1つにまとめる場合、代表的なツールはILMergeとCostura.Fodyです。

ILMergeはMicrosoftが提供する公式ツールで、.NET Frameworkのアセンブリを統合するために設計されています。

コマンドラインから簡単に利用でき、複数のDLLやEXEを1つのアセンブリに結合可能です。

Costura.FodyはFodyというIL操作ツールのアドインで、ビルド時にDLLを実行ファイルに埋め込む仕組みを提供します。

Visual StudioのNuGetパッケージとして導入しやすく、設定ファイルを用意するだけで自動的にDLLを埋め込めるため、手軽に利用できます。

この2つは.NET Framework向けに最も広く使われている選択肢であり、安定性やドキュメントの充実度も高いです。

ただし、ILMergeは.NET Framework専用であり、.NET Coreや.NET 5以降には対応していません。

.NET Core/.NET 5+向けの候補

.NET Coreや.NET 5以降の環境では、ILMergeは公式にサポートされていません。

そのため、代わりにCostura.Fodyが利用されることが多いです。

Costura.Fodyは.NET Coreや.NET 5+でも動作する場合があり、特に単純なDLL埋め込みには問題なく使えます。

また、.NET Core以降では、Microsoftが提供するPublishSingleFile機能が標準で利用可能です。

これはビルド時にアプリケーションと依存DLLを1つの実行ファイルにまとめる機能で、ネイティブコードのバンドルや自己解凍もサポートしています。

Visual Studioやdotnet publishコマンドのオプションで簡単に有効化できます。

さらに、Costura.Fodyの代わりにILRepackというオープンソースのツールもあります。

ILRepackはILMergeの代替として開発されており、.NET Core対応も進んでいますが、公式サポートは限定的です。

ILMergeとCostura.Fodyの位置づけ

ILMergeは複数のアセンブリを1つのアセンブリに結合する「結合型」のツールです。

実行ファイルとDLLを1つのアセンブリにまとめるため、起動時の展開処理は不要で、パフォーマンス面で有利な場合があります。

ただし、.NET Framework専用であり、最新の.NET環境では使えません。

一方、Costura.Fodyは「埋め込み型」のツールで、DLLを実行ファイルにリソースとして埋め込み、実行時にメモリ上で展開して読み込みます。

ビルド時に自動で埋め込み処理が行われるため、導入が簡単で、.NET Frameworkだけでなく.NET Coreや.NET 5+でも動作することがあります。

ただし、起動時に展開処理が発生するため、起動速度にわずかな影響が出ることがあります。

ツール名結合方式対応フレームワーク起動時の展開処理導入の手軽さメンテナンス状況
ILMerge結合.NET Frameworkなし公式だが更新は少なめ
Costura.Fody埋め込み.NET Framework, .NET Core, .NET 5+あり簡単活発に更新されている
ILRepack結合.NET Framework, 一部.NET Coreなしオープンソースで継続中
PublishSingleFile結合.NET Core, .NET 5+なし簡単Microsoft公式

代替ツールの簡単な紹介

ILMergeやCostura.Fody以外にも、いくつかの代替ツールがあります。

  • ILRepack

ILMergeのオープンソース代替で、ILMergeと似た結合方式を採用しています。

ILMergeよりも柔軟なオプションがあり、.NET Core対応も進んでいます。

コマンドラインツールとして利用可能で、GitHubでソースコードが公開されています。

  • Fodyの他のアドイン

FodyはCostura以外にも多くのアドインがあり、アセンブリの操作や最適化に使えます。

例えば、ModuleInitPropertyChangedなど、特定の機能を追加するためのツール群です。

Costuraと組み合わせて使うことで、より高度なビルドカスタマイズが可能です。

  • .NET CoreのPublishSingleFile機能

.NET Core 3.0以降で利用できる標準機能で、アプリケーションと依存DLLを1つの実行ファイルにまとめます。

ネイティブコードのバンドルや自己解凍もサポートし、追加のツールを使わずに単一ファイル配布が可能です。

Visual StudioやCLIから簡単に設定できます。

  • Mono.Cecilを使ったカスタムツール

Mono.Cecilは.NETアセンブリの読み書きを行うライブラリで、独自にアセンブリ統合ツールを作成する際に利用されます。

高度なカスタマイズが可能ですが、開発コストが高いため一般的な用途にはあまり使われません。

これらのツールはプロジェクトの要件や対象フレームワーク、配布形態に応じて使い分けることが重要です。

ILMergeの使い方

インストール手順

ILMergeはMicrosoftが提供するコマンドラインツールで、公式サイトやNuGetから入手できます。

最も簡単な方法はNuGetを使うことです。

Visual Studioのパッケージマネージャーコンソールで以下のコマンドを実行してください。

Install-Package ilmerge

これにより、プロジェクトのpackagesフォルダにILMergeがインストールされ、packages\ilmerge.x.x.x\tools\ILMerge.exeに実行ファイルが配置されます。

また、ILMergeの公式サイト(https://www.microsoft.com/en-us/download/details.aspx?id=17630)からインストーラーをダウンロードしてインストールする方法もあります。

インストール後は、コマンドプロンプトでilmergeコマンドが使えるように環境変数PATHを設定すると便利です。

最小構成のコマンド例

ILMergeを使って、App.exeLibrary.dllを1つの実行ファイルにまとめる最小限のコマンドは以下の通りです。

ilmerge /out:AppMerged.exe App.exe Library.dll

このコマンドは、App.exeLibrary.dllを結合し、AppMerged.exeという名前の単一実行ファイルを生成します。

特別なオプションを指定しなければ、ILMergeはデフォルトの動作でアセンブリを結合します。

主要オプション /out /internalize /ndebug

ILMergeには多くのオプションがありますが、よく使われる主要なものを紹介します。

  • /out:<ファイル名>

出力ファイル名を指定します。

必須のオプションで、結合後の実行ファイル名やDLL名を決めます。

  • /internalize

結合したDLLの公開型(publicなクラスやメンバー)を内部型(internal)に変更します。

これにより、結合後のアセンブリ外からは結合したDLLの型が見えなくなり、名前空間の衝突や型の重複を防げます。

特に複数のDLLに同じ名前の型がある場合に有効です。

  • /ndebug

デバッグ情報(PDBファイル)を無視して結合します。

デバッグ情報が不要なリリースビルドで使うことが多いです。

逆にデバッグ情報を保持したい場合は指定しません。

これらのオプションを組み合わせる例は以下の通りです。

ilmerge /out:AppMerged.exe /internalize /ndebug App.exe Library.dll

署名付きアセンブリを扱うポイント

署名付きアセンブリ(Strong Name署名付き)をILMergeで結合する場合は注意が必要です。

署名付きアセンブリは、強力な名前(Strong Name)で保護されており、結合後も署名の整合性を保つ必要があります。

ILMergeは署名付きアセンブリの結合をサポートしていますが、結合後のアセンブリに再署名を行う必要があります。

これには、強力な名前キー(.snkファイル)が必要です。

署名付きアセンブリを結合する際のポイントは以下の通りです。

  • 結合後のアセンブリに署名を付けるため、/keyfile:<キーのパス>オプションを使います
ilmerge /out:AppMerged.exe /keyfile:MyKey.snk App.exe Library.dll
  • すべての入力アセンブリが署名付きである必要があります。署名なしのアセンブリと混在するとエラーになります
  • 署名付きアセンブリの結合は、署名の整合性を保つためにビルドプロセスの一部として慎重に扱うことが重要です

リファレンス解決と入力順のコツ

ILMergeは結合するアセンブリの依存関係を解決しながら処理しますが、入力ファイルの順序が重要です。

基本的に、メインの実行ファイル(EXE)を最初に指定し、その後に依存DLLを列挙します。

例えば、App.exeLibrary.dllに依存している場合は以下のようにします。

ilmerge /out:AppMerged.exe App.exe Library.dll

逆にDLLを先に指定すると、依存関係の解決に失敗することがあります。

また、ILMergeは参照解決のために同じフォルダ内のアセンブリを探しますが、依存DLLが別のフォルダにある場合は、/lib:<フォルダパス>オプションで検索パスを追加できます。

ilmerge /out:AppMerged.exe /lib:libs App.exe Library.dll

さらに、複雑な依存関係がある場合は、結合するDLLをすべて明示的に指定し、順序を正しく保つことがトラブル回避のポイントです。

以下はILMergeの基本的な使い方を示すサンプルコードです。

実際にはコマンドラインツールなので、C#コード内で呼び出す場合はProcessクラスを使いますが、ここではコマンド例を示します。

// ILMergeを使ってApp.exeとLibrary.dllを結合するコマンド例
// 実行はコマンドプロンプトで行います
// ilmerge /out:AppMerged.exe /internalize /ndebug App.exe Library.dll

このようにILMergeはコマンドラインから簡単に使え、オプションを組み合わせることで柔軟にアセンブリを統合できます。

ILMerge高度な設定

リソースとXMLドキュメントの統合

ILMergeは単に複数のアセンブリを結合するだけでなく、リソースファイルやXMLドキュメントファイルの統合にも対応しています。

リソースとは、画像や文字列、設定ファイルなどの埋め込みデータのことを指します。

XMLドキュメントは、C#のコードコメントから生成されるAPIドキュメントファイル(.xml)です。

ILMergeはデフォルトでアセンブリに埋め込まれたリソースを結合しますが、外部のXMLドキュメントファイルは自動的には統合されません。

XMLドキュメントを統合したい場合は、ILMergeのオプションで明示的に指定するか、ビルド後に別途マージ処理を行う必要があります。

例えば、XMLドキュメントを結合するには、ILMergeの/xmldocsオプションを使います。

これにより、入力アセンブリのXMLドキュメントを1つにまとめて出力できます。

ilmerge /out:AppMerged.exe /xmldocs App.exe Library.dll

リソースの統合に関しては、ILMergeは埋め込みリソースを保持しつつ、名前の衝突を避けるためにリソース名を調整します。

複数のアセンブリで同じ名前のリソースがある場合は、/internalizeオプションと組み合わせて使うと安全です。

PDBファイル保持とデバッグ情報

デバッグを行う際に重要なのがPDBファイル(プログラムデータベース)です。

ILMergeはPDBファイルの統合もサポートしており、結合後のアセンブリに対応したPDBファイルを生成できます。

PDBファイルを保持するには、ILMergeの/ndebugオプションを指定しないことがポイントです。

/ndebugはデバッグ情報を無視するため、デバッグ情報を残したい場合は省略します。

また、PDBファイルの統合はILMergeのバージョンや環境によって挙動が異なることがあるため、結合後に生成されるPDBファイルが正しく機能しているかをVisual Studioなどで確認することが重要です。

以下はPDBファイルを保持して結合する例です。

ilmerge /out:AppMerged.exe App.exe Library.dll

この場合、App.exe.pdbLibrary.dll.pdbが存在すれば、ILMergeはそれらを統合してAppMerged.pdbを生成します。

MSBuildタスクへの組み込み

ILMergeはコマンドラインツールですが、MSBuildのビルドプロセスに組み込むことも可能です。

これにより、ビルド時に自動的にアセンブリ統合を行い、手動でコマンドを実行する手間を省けます。

MSBuildにILMergeを組み込むには、プロジェクトファイル(.csproj)にカスタムターゲットを追加します。

以下は簡単な例です。

<Target Name="AfterBuild">
  <Exec Command="ilmerge /out:$(OutputPath)AppMerged.exe $(OutputPath)App.exe $(OutputPath)Library.dll" />
</Target>

この設定はビルド完了後にILMergeを実行し、App.exeLibrary.dllを結合してAppMerged.exeを生成します。

より高度な設定では、MSBuildのItemGroupで結合対象のDLLを管理したり、条件分岐でDebug/Releaseビルドごとに異なるオプションを指定したりできます。

また、ILMerge専用のMSBuildタスクを提供するNuGetパッケージも存在し、これを利用するとより簡単に統合処理を組み込めます。

大規模ソリューションでのバッチ運用

大規模なソリューションでは、複数のプロジェクトが依存関係を持ち、多数のDLLが生成されます。

ILMergeを使ってこれらを一括で統合する場合、手動でコマンドを実行するのは非効率です。

バッチファイルやPowerShellスクリプトを作成し、複数のILMergeコマンドを自動化する方法が一般的です。

例えば、以下のようなPowerShellスクリプトで複数のアプリケーションをまとめて処理できます。

$projects = @(
  @{Output="App1Merged.exe"; Inputs=@("App1.exe", "LibA.dll", "LibB.dll")},
  @{Output="App2Merged.exe"; Inputs=@("App2.exe", "LibC.dll")}
)
foreach ($proj in $projects) {
  $inputFiles = $proj.Inputs -join " "
  $cmd = "ilmerge /out:$($proj.Output) $inputFiles"
  Write-Host "Executing: $cmd"
  Invoke-Expression $cmd
}

このように、複数の結合処理を一括で実行できるため、ビルドパイプラインの一部として組み込みやすくなります。

また、依存関係の管理やDLLのバージョン整合性を保つために、結合対象のDLLリストを外部ファイルで管理し、スクリプトで読み込む方法もあります。

CIパイプラインへの統合例

継続的インテグレーション(CI)環境でILMergeを使う場合、ビルド完了後に自動的にアセンブリ統合を行うステップを追加します。

Azure DevOpsやGitHub Actions、JenkinsなどのCIツールで実行可能です。

例えば、Azure DevOpsのYAMLパイプラインでILMergeを使う例は以下の通りです。

- task: CmdLine@2

  inputs:
    script: |
      ilmerge /out:$(Build.ArtifactStagingDirectory)/AppMerged.exe $(Build.ArtifactStagingDirectory)/App.exe $(Build.ArtifactStagingDirectory)/Library.dll

このステップはビルド成果物が配置されたディレクトリでILMergeを実行し、単一の実行ファイルを生成します。

CIパイプラインに組み込む際のポイントは以下です。

  • ILMergeの実行環境を事前に用意する(NuGetパッケージの復元やインストール)
  • ビルド成果物のパスを正確に指定する
  • エラー発生時にパイプラインが停止するように設定する
  • 結合後のファイルをアーティファクトとして保存し、配布やデプロイに利用する

これにより、手動作業を減らし、常に最新の統合済み実行ファイルを自動生成できるため、品質向上と運用効率化が期待できます。

Costura.Fodyの使い方

NuGet導入フロー

Costura.Fodyを使うには、まずVisual StudioのNuGetパッケージマネージャーからFodyCostura.Fodyの2つのパッケージをインストールします。

これにより、ビルド時にDLLを自動的に埋め込む仕組みがプロジェクトに組み込まれます。

手順は以下の通りです。

  1. Visual Studioで対象のプロジェクトを開きます。
  2. メニューバーの「ツール」→「NuGet パッケージ マネージャー」→「パッケージ マネージャー コンソール」を開きます。
  3. 以下のコマンドを順に実行します。
Install-Package Fody
Install-Package Costura.Fody

これでpackages.config*.csprojに必要な参照が追加され、ビルド時にCostura.Fodyが動作する準備が整います。

FodyWeavers.xmlの最小構成

Costura.Fodyを有効にするためには、プロジェクトのルートディレクトリにFodyWeavers.xmlという設定ファイルを作成し、以下の内容を記述します。

<?xml version="1.0" encoding="utf-8"?>
<Weavers>
  <Costura />
</Weavers>

このファイルはFodyの拡張機能を指定するもので、<Costura />タグを入れることでCostura.Fodyがビルド時に動作し、DLLの埋め込み処理を行います。

FodyWeavers.xmlは必ずプロジェクトのルートに置き、ビルド時に読み込まれる必要があります。

ファイルがないとCostura.Fodyは動作しません。

自動埋め込みの仕組み

Costura.Fodyはビルド時に、プロジェクトが参照しているDLLを実行ファイルに埋め込みます。

具体的には、参照DLLをリソースとしてEXEファイルに埋め込み、実行時にメモリ上で展開して読み込みます。

この仕組みは、FodyがIL(中間言語)コードを解析・書き換えし、AssemblyResolveイベントをフックして埋め込まれたDLLを解凍・ロードするコードを自動生成することで実現しています。

埋め込み対象は、プロジェクトの参照DLLのうちCopy Localtrueに設定されているものが基本です。

不要なDLLを埋め込みたくない場合は、FodyWeavers.xmlで除外設定も可能です。

この自動埋め込みにより、配布時は単一の実行ファイルだけで済み、依存DLLの管理が不要になります。

解凍タイミングとAssemblyResolve

Costura.Fodyが埋め込んだDLLは、実行時に必要になったタイミングでメモリ上に展開されます。

具体的には、.NETのAppDomain.AssemblyResolveイベントが発生した際に、埋め込みリソースから該当DLLを読み込み、動的にアセンブリをロードします。

このため、実行ファイルの起動直後にすべてのDLLが展開されるわけではなく、必要になった時点で順次展開される仕組みです。

これにより、起動時の負荷を分散できます。

ただし、ネイティブDLL(C++で作られたDLLなど)を埋め込んだ場合は、通常のマネージDLLとは異なり、ファイルとして一時的にディスクに展開されることがあります。

これもCostura.Fodyが自動で処理します。

デバッグビルドとリリースビルドの差異

Costura.Fodyはデバッグビルドとリリースビルドの両方で動作しますが、動作やビルド成果物にいくつかの違いがあります。

  • デバッグビルド

デバッグ情報(PDBファイル)が含まれるため、デバッグ時にブレークポイントやステップ実行が可能です。

埋め込みDLLもデバッグ用のPDBを含む場合が多く、デバッグがしやすい環境が保たれます。

  • リリースビルド

最適化が有効になり、PDBファイルが含まれないか縮小されます。

埋め込みDLLも最適化された状態で埋め込まれ、ファイルサイズが小さくなります。

起動速度やパフォーマンスが向上します。

ただし、Costura.Fodyは埋め込みDLLの展開処理を行うため、デバッグビルドでも起動時にわずかな遅延が発生することがあります。

デバッグ時にDLLの動的ロードに関する問題が起きた場合は、FodyWeavers.xmlでCosturaの動作を一時的に無効化することも検討してください。

以下はCostura.Fodyを使った簡単なサンプルコード例です。

実際のDLL埋め込みはビルド時に自動で行われるため、コード上で特別な処理は不要です。

using System;
class Program
{
    static void Main()
    {
        // ここでは埋め込まれたDLLの機能を呼び出す例
        Console.WriteLine("Costura.Fodyで埋め込んだDLLの機能を呼び出します。");
        // 例えば、埋め込んだライブラリのクラスを使う
        var helper = new HelperLibrary.Helper();
        helper.DoWork();
        Console.WriteLine("処理が完了しました。");
    }
}
Costura.Fodyで埋め込んだDLLの機能を呼び出します。
HelperLibraryの作業を実行中...
処理が完了しました。

このように、Costura.Fodyはビルド時にDLLを埋め込み、実行時に自動で展開・ロードするため、開発者は特別なコードを書かずに単一ファイル配布が可能になります。

Costura.Fodyのカスタマイズ

個別DLLの除外設定

Costura.Fodyはデフォルトでプロジェクトに参照されているすべてのDLLを埋め込みますが、特定のDLLだけを除外したい場合があります。

例えば、外部の大きなライブラリや、別途配布したいDLLを埋め込みたくないケースです。

個別DLLの除外は、FodyWeavers.xml<Costura>タグ内に<ExcludeAssemblies>要素を追加して行います。

除外したいDLL名をカンマ区切りで指定します。

<Weavers>
  <Costura>
    <ExcludeAssemblies>ExcludeLib1,ExcludeLib2</ExcludeAssemblies>
  </Costura>
</Weavers>

この設定をすると、ExcludeLib1.dllExcludeLib2.dllは埋め込み対象から外れ、通常通り外部ファイルとして配置されます。

DLL名は拡張子なしのアセンブリ名で指定し、大文字・小文字は区別されません。

ワイルドカードと正規表現

Costura.Fodyでは、除外設定にワイルドカードや正規表現を使うことも可能です。

これにより、複数のDLLをまとめて除外したり、特定のパターンにマッチするDLLだけを除外したりできます。

ワイルドカードは*?を使い、例えばExcludeAssembliesMyLib*と指定すると、MyLibCore.dllMyLibUtils.dllなど、MyLibで始まるすべてのDLLが除外されます。

正規表現を使う場合は、<ExcludeAssembliesRegex>タグを使います。

例えば、以下のように記述します。

<Weavers>
  <Costura>
    <ExcludeAssembliesRegex>^TestLib.*$</ExcludeAssembliesRegex>
  </Costura>
</Weavers>

この例では、TestLibで始まるすべてのDLLが除外されます。

ワイルドカードと正規表現は併用可能ですが、設定が複雑になるため注意が必要です。

NativeDllの取り込み

Costura.FodyはマネージDLLだけでなく、ネイティブDLL(C++などで作成されたアンマネージDLL)も埋め込むことができます。

ネイティブDLLは通常、実行時にファイルとしてディスクに展開され、そこからロードされます。

ネイティブDLLを埋め込むには、FodyWeavers.xml<Costura>タグ内に<IncludeNativeLibraries>trueに設定します。

<Weavers>
  <Costura>
    <IncludeNativeLibraries>true</IncludeNativeLibraries>
  </Costura>
</Weavers>

この設定をすると、Copy LocaltrueのネイティブDLLも埋め込み対象となり、実行時に一時フォルダに展開されてロードされます。

ただし、ネイティブDLLの展開先はOSや環境によって異なるため、アンチウイルスソフトの誤検知やファイルアクセス権限に注意が必要です。

PreloadOrderで読み込み順制御

Costura.Fodyは埋め込んだDLLを必要に応じて動的にロードしますが、依存関係のあるDLLは特定の順序で読み込む必要があります。

読み込み順序が不適切だと、FileNotFoundExceptionTypeLoadExceptionが発生することがあります。

PreloadOrderオプションを使うと、DLLの読み込み順序を明示的に制御できます。

FodyWeavers.xml<Costura>タグ内に以下のように記述します。

<Weavers>
  <Costura>
    <PreloadOrder>
      <Assembly>DependencyLib1</Assembly>
      <Assembly>DependencyLib2</Assembly>
    </PreloadOrder>
  </Costura>
</Weavers>

この例では、DependencyLib1.dllが先にロードされ、その後にDependencyLib2.dllがロードされます。

依存関係のあるDLLはこの順序で読み込まれるため、依存解決がスムーズになります。

PreloadOrderに指定しなかったDLLは、必要に応じて遅延ロードされます。

ファイルサイズを抑えるヒント

Costura.FodyでDLLを埋め込むと、実行ファイルのサイズが大きくなる傾向があります。

ファイルサイズを抑えるためのポイントをいくつか紹介します。

  • 不要なDLLを除外する

先述のExcludeAssembliesExcludeAssembliesRegexを使い、使わないDLLや大きなライブラリを埋め込みから除外します。

  • Releaseビルドで最適化を有効にする

リリースビルドではコード最適化や不要なデバッグ情報の削除が行われるため、ファイルサイズが小さくなります。

  • DLLの圧縮を検討する

Costura.Fodyは埋め込みDLLを圧縮する機能を持っています。

IncludeDebugSymbolsDisableCompressionオプションを調整し、圧縮を有効にすることでサイズを削減できます。

<Weavers>
  <Costura>
    <DisableCompression>false</DisableCompression>
  </Costura>
</Weavers>
  • 不要なリソースを削除する

埋め込みDLLに含まれる不要なリソースやローカライズファイルを削除してから埋め込むと、サイズ削減につながります。

  • 依存関係の見直し

プロジェクトの参照を整理し、不要な依存DLLを減らすことも効果的です。

これらの工夫を組み合わせることで、Costura.Fodyを使った単一ファイル配布でもファイルサイズを抑えつつ、利便性を維持できます。

ILMergeとCosturaの比較

対応フレームワークとメンテナンス状況

ILMergeはMicrosoftが開発したツールで、主に.NET Framework向けに設計されています。

公式に.NET Framework 4.xまでのサポートが明確であり、.NET Coreや.NET 5以降の環境では公式対応していません。

そのため、最新の.NET環境での利用は推奨されておらず、メンテナンスも長期間活発ではありません。

一方、Costura.FodyはFodyというIL操作フレームワークのアドインとして開発されており、.NET Frameworkだけでなく.NET Coreや.NET 5以降の環境でも動作することが多いです。

コミュニティベースで活発にメンテナンスされており、最新の.NET環境に対応するアップデートも継続的に行われています。

まとめると、ILMergeは安定した.NET Framework向けのツールとして信頼性が高いですが、最新環境には不向きです。

Costura.Fodyは幅広いフレームワークに対応し、活発なメンテナンスが行われているため、将来的な互換性を重視する場合に適しています。

実行ファイルサイズと起動速度

ILMergeは複数のアセンブリを1つのアセンブリに結合するため、実行ファイルは単一の大きなファイルになります。

DLLは結合後に展開処理が不要なため、起動時のオーバーヘッドはほとんどありません。

結果として、起動速度は比較的速い傾向があります。

ただし、ILMergeで結合したファイルはサイズが大きくなることが多く、特に多くのDLLを結合するとファイルサイズがかなり増加します。

Costura.FodyはDLLを実行ファイルにリソースとして埋め込み、実行時にメモリ上で展開・ロードします。

この展開処理が起動時に発生するため、ILMergeに比べて起動速度がわずかに遅くなることがあります。

ファイルサイズは埋め込みDLLの分だけ増加しますが、Costura.Fodyは圧縮機能を備えているため、ILMergeよりもサイズを抑えられる場合があります。

項目ILMergeCostura.Fody
実行ファイルサイズ大きくなる傾向あり圧縮により比較的小さく抑えられる場合あり
起動速度速い(展開処理なし)やや遅い(実行時展開あり)

ワークフローへの組み込みやすさ

ILMergeはコマンドラインツールとして提供されており、MSBuildのカスタムターゲットやバッチスクリプトに組み込みやすいです。

ただし、設定や依存関係の管理がやや複雑で、特に大規模プロジェクトでは入力ファイルの順序やオプション調整に注意が必要です。

Costura.FodyはNuGetパッケージとして導入し、FodyWeavers.xmlで簡単に設定できるため、Visual Studioのビルドプロセスに自然に組み込めます。

特別なスクリプトやコマンドを用意する必要がなく、ビルド時に自動でDLL埋め込みが行われるため、開発者の手間が少ないです。

そのため、ワークフローへの組み込みやすさではCostura.Fodyが優れており、特に継続的インテグレーション(CI)環境やチーム開発での運用がスムーズです。

ライセンスと商用利用の観点

ILMergeはMicrosoftが提供しており、基本的に自由に商用利用が可能です。

特別なライセンス料や制限はなく、安心して利用できます。

Costura.Fodyはオープンソースで、MITライセンスの下で配布されています。

MITライセンスは非常に寛容で、商用利用や改変、再配布が自由に行えます。

ただし、オープンソースであるため、サポートはコミュニティベースであり、商用サポートはありません。

どちらのツールも商用プロジェクトで問題なく利用できますが、Costura.Fodyは依存するFodyフレームワークやその他のNuGetパッケージのライセンスも確認しておくと安心です。

以上の比較を踏まえ、プロジェクトの対象フレームワークや運用環境、パフォーマンス要件に応じてILMergeとCostura.Fodyを選択するとよいでしょう。

マージ後のテストとデバッグ

自動テストでチェックする項目

アセンブリをILMergeやCostura.Fodyで統合した後は、動作確認のために自動テストを実行することが重要です。

特に以下の項目を重点的にチェックします。

  • 基本機能の動作確認

アプリケーションの主要な機能が正常に動作するかをテストします。

UI操作やAPI呼び出し、ファイル入出力など、ユーザーが利用する機能を網羅的に検証します。

  • 依存DLLの機能呼び出し

統合したDLL内のクラスやメソッドが正しく呼び出せるかを確認します。

DLLの埋め込みや結合により、型解決やリフレクションが影響を受けることがあるため、特に注意が必要です。

  • 例外発生時の挙動

例外が発生した場合に適切にキャッチされ、ログ出力やエラーハンドリングが機能するかをテストします。

マージ後は例外のスタックトレースが変わることがあるため、例外処理の動作確認は必須です。

  • 起動・終了処理の安定性

アプリケーションの起動や終了時に異常がないかをチェックします。

特にCostura.Fodyのように実行時にDLLを展開する場合、起動時の処理に問題が起きやすいです。

  • パフォーマンスの基本チェック

起動時間や主要処理のレスポンスが大幅に悪化していないかを確認します。

マージによる影響を早期に検出するために、ベンチマークテストを組み込むことも有効です。

これらのテストは、単体テストや統合テスト、自動UIテストなど、既存のテストフレームワークを活用して実施します。

マージ後のビルドで自動的にテストが走るようにCI環境に組み込むと効率的です。

例外スタックトレースの確認方法

アセンブリを統合すると、例外発生時のスタックトレースが変わることがあります。

特にILMergeでは複数のDLLが1つのアセンブリに結合されるため、元のDLL名やメソッド名がわかりにくくなる場合があります。

スタックトレースを正しく確認するためのポイントは以下の通りです。

  • PDBファイルの統合と配置

ILMergeでPDBファイルを統合し、結合後の実行ファイルと同じ場所に配置します。

これにより、Visual Studioのデバッガやログ解析ツールで正確なスタックトレースが得られます。

  • 例外ログの詳細化

例外発生時にException.ToString()を使って詳細なスタックトレースをログに出力します。

可能であれば、InnerExceptionも再帰的にログに含めてください。

  • Costura.FodyのAssemblyResolveイベントの理解

Costura.Fodyは実行時にDLLを展開し、AssemblyResolveイベントでアセンブリをロードします。

このため、例外の発生箇所が動的にロードされたDLL内になることがあり、スタックトレースの解釈に注意が必要です。

  • デバッグビルドでの検証

デバッグビルドで例外を再現し、Visual Studioのデバッガでスタックトレースを確認します。

リリースビルドでは最適化により情報が省略されることがあるため、デバッグビルドでの検証が重要です。

メモリ使用量とハンドル数の計測

マージ後のアプリケーションがメモリリークやリソース不足を起こしていないかを確認するため、メモリ使用量やハンドル数の計測を行います。

  • Windowsのタスクマネージャーやリソースモニター

実行中のプロセスのメモリ使用量(ワーキングセット、プライベートバイト)やハンドル数を監視します。

マージ前後で比較し、異常な増加がないかをチェックします。

  • プロファイリングツールの活用

Visual Studioの診断ツールやJetBrains dotMemory、Redgate ANTS Memory Profilerなどを使い、詳細なメモリ使用状況やガベージコレクションの挙動を分析します。

  • ハンドルリークの検出

ハンドル数が増え続ける場合は、ファイルハンドルやウィンドウハンドルのリークが疑われます。

SysinternalsのProcess Explorerなどでハンドルの種類と数を詳細に調査します。

  • 自動化された監視

CI環境やテスト環境でメモリ使用量を定期的に記録し、閾値を超えた場合にアラートを出す仕組みを導入すると効果的です。

パフォーマンスベンチマーク手法

マージ後のパフォーマンスが許容範囲内かを評価するため、ベンチマークテストを実施します。

以下の手法が一般的です。

  • 起動時間計測

アプリケーションの起動開始からメインウィンドウ表示までの時間を計測します。

ILMergeは展開処理がないため起動が速い傾向にありますが、Costura.Fodyは埋め込みDLLの展開が起動遅延の原因になることがあります。

  • 主要処理のレスポンス測定

ユーザー操作やAPI呼び出しの処理時間を計測し、マージ前後で比較します。

負荷テストツールや自動UIテストツールを使うと効率的です。

  • CPU使用率の監視

長時間動作時のCPU使用率を監視し、異常な高負荷が発生していないかを確認します。

  • メモリ使用量の推移

ベンチマーク中のメモリ使用量の変化を記録し、リークや過剰なメモリ消費がないかをチェックします。

  • 自動化ベンチマークツールの利用

BenchmarkDotNetなどのベンチマークフレームワークを使い、コード単位でのパフォーマンス測定も可能です。

これらのベンチマーク結果をもとに、必要に応じてILMergeやCostura.Fodyの設定を調整し、最適なパフォーマンスを目指します。

セキュリティ・ライセンスの注意点

逆アセンブル耐性の向上可否

ILMergeやCostura.Fodyで複数のDLLを1つにまとめることは、逆アセンブル(リバースエンジニアリング)に対する一定の抑止効果を期待できます。

複数のアセンブリが1つに統合されることで、コードの構造が変わり、解析がやや複雑になるためです。

しかし、これらのツールは本質的に逆アセンブル耐性を高めるためのセキュリティ機能ではありません。

ILMergeは単にILコードを結合するだけであり、Costura.FodyはDLLを埋め込んで実行時に展開する仕組みなので、いずれもILコードは容易に抽出可能です。

逆アセンブル耐性を強化したい場合は、別途コード難読化(Obfuscation)ツールの導入が必要です。

難読化ツールはコードの可読性を下げ、リバースエンジニアリングを困難にします。

ILMergeやCostura.Fodyと組み合わせて使うことも可能ですが、難読化後のアセンブリを統合するか、統合後に難読化を行うかは運用ポリシーに応じて検討してください。

強名署名鍵の扱い

強名署名(Strong Name)は、アセンブリの改ざん検出や一意性の保証に使われる重要な仕組みです。

ILMergeやCostura.Fodyでアセンブリを統合する際は、強名署名鍵の扱いに注意が必要です。

ILMergeでは、署名付きアセンブリを結合した後に再署名を行うため、結合時に/keyfileオプションで秘密鍵(.snkファイル)を指定します。

これにより、結合後のアセンブリに正しい署名が付与され、改ざん検出が維持されます。

Costura.Fodyは埋め込み方式のため、元のアセンブリの署名は保持されますが、実行ファイル自体に署名を付ける場合は別途署名処理が必要です。

特にClickOnceやMSIXなどの配布形式では、署名の整合性が重要です。

秘密鍵は厳重に管理し、外部に漏れないようにしてください。

CI/CD環境での署名処理は、セキュリティを考慮して安全なストレージやキーストアを利用することが推奨されます。

サードパーティDLLのライセンス確認

アプリケーションに含まれるサードパーティDLLのライセンスは必ず確認してください。

ILMergeやCostura.FodyでDLLを統合・埋め込みすると、配布形態が変わるため、ライセンス条件に抵触する可能性があります。

特に、GPLやLGPLなどのコピーレフト系ライセンスは、DLLを結合・埋め込みすることでアプリケーション全体にライセンスの影響が及ぶ場合があります。

商用利用やクローズドソース配布を検討している場合は注意が必要です。

MITやApache Licenseなどの寛容なライセンスであっても、ライセンス文書の同梱や著作権表示の義務があることが多いため、配布物に適切に含めることが求められます。

ライセンス違反を防ぐために、使用しているすべてのサードパーティDLLのライセンスを一覧化し、配布形態に応じた対応を行うことが重要です。

アップデート配信時の整合性チェック

アセンブリを統合した単一ファイルをアップデート配信する場合、ファイルの整合性チェックが重要です。

改ざんや破損を防ぎ、ユーザーに安全なファイルを届けるためです。

署名付きアセンブリの場合は、強名署名によって改ざん検出が可能ですが、配布ファイル全体の整合性を保証するために、デジタル署名(Authenticode署名)を付与することが推奨されます。

これにより、WindowsのSmartScreenやアンチウイルスソフトの警告を回避しやすくなります。

また、アップデート配信システム側でハッシュ値(SHA-256など)を用いた検証を行い、ダウンロード時にファイルの整合性をチェックする仕組みを導入すると安全性が高まります。

Costura.Fodyのように実行時にDLLを展開する方式では、展開時のファイルアクセス権限や一時ファイルの管理にも注意が必要です。

悪意のある改ざんを防ぐため、展開先のフォルダを適切に制限し、不要なファイルを残さない運用が望まれます。

アップデート配信の設計段階から、署名や整合性チェックの仕組みを組み込み、セキュリティリスクを最小限に抑えることが重要です。

デプロイメントへの組み込み

ClickOnceやMSIXとの併用

ClickOnceやMSIXは、Windowsアプリケーションの配布と更新を簡単に行うための仕組みです。

ILMergeやCostura.FodyでDLLを1つの実行ファイルにまとめた後、これらの配布技術と組み合わせることで、配布の利便性をさらに高められます。

ClickOnceは、アプリケーションの依存ファイルを自動的に管理し、オンラインやネットワーク経由でのインストール・更新をサポートします。

ILMergeやCostura.Fodyで単一ファイル化した実行ファイルをClickOnceの配布物に含めることで、依存DLLの管理ミスを防ぎつつ、ClickOnceの自動更新機能を活用できます。

MSIXはWindows 10以降で推奨されるパッケージング形式で、アプリケーションのインストール、更新、アンインストールを安全かつ効率的に行えます。

単一ファイル化した実行ファイルをMSIXパッケージに含めることで、配布ファイル数を減らし、パッケージの整合性を保ちやすくなります。

ただし、ClickOnceやMSIXの仕組み自体が依存関係の管理を行うため、単一ファイル化による恩恵は限定的な場合もあります。

特にClickOnceでは、DLLの差分更新が難しくなるため、更新サイズが大きくなる可能性があります。

運用方針に応じて使い分けることが重要です。

自己解凍式インストーラでの利用

ILMergeやCostura.Fodyで単一ファイル化した実行ファイルは、自己解凍式インストーラ(Self-Extracting Archive)に組み込むことで、配布の利便性をさらに向上させられます。

自己解凍式インストーラは、圧縮されたファイル群を展開し、インストール処理を自動で行う実行ファイルです。

単一ファイル化された実行ファイルをインストーラに含めることで、配布物のファイル数を減らし、ユーザーの操作を簡素化できます。

また、自己解凍式インストーラはネットワーク経由での配布やUSBメモリなどの物理メディアでの配布に適しており、インストール時に必要なファイルを一括で展開できるため、依存関係の問題を回避しやすくなります。

代表的なツールとしては、7-Zipの自己解凍機能やInno Setup、NSISなどがあります。

これらのツールでILMergeやCostura.Fodyで作成した単一ファイルを含むインストーラを作成し、配布を自動化すると効果的です。

コンテナ化環境での効果

Dockerなどのコンテナ環境で.NETアプリケーションを運用する場合、ILMergeやCostura.Fodyによる単一ファイル化は配布やイメージサイズの最適化に寄与します。

コンテナイメージはファイル数が多いとレイヤー管理が複雑になり、ビルド時間やデプロイ時間が増加します。

単一ファイル化により、依存DLLをまとめて1つのファイルにできるため、ファイル数を減らしイメージの管理がシンプルになります。

また、単一ファイル化された実行ファイルは、コンテナ内での起動時に依存関係の解決が不要になるため、起動速度の安定化にもつながります。

ただし、.NET Core以降ではdotnet publishPublishSingleFileオプションが標準で利用可能なため、ILMergeやCostura.Fodyを使わずに単一ファイル化を実現できるケースも多いです。

コンテナ環境では標準機能の活用を優先しつつ、必要に応じてこれらのツールを検討するとよいでしょう。

オンライン配布とオフライン配布の違い

オンライン配布は、インターネット経由でアプリケーションをダウンロード・更新する方式です。

単一ファイル化された実行ファイルは、オンライン配布でのダウンロードサイズを減らし、依存DLLの管理を簡素化します。

更新時も単一ファイルを差し替えるだけで済むため、ユーザーの手間が少なくなります。

一方、オフライン配布は、USBメモリやDVDなどの物理メディアで配布する方式です。

依存DLLを含む複数ファイルを配布すると、ファイルの紛失やバージョン不整合のリスクが高まります。

単一ファイル化により、これらのリスクを大幅に軽減でき、オフライン環境でも確実に動作する配布物を作成できます。

ただし、オンライン配布では差分更新やパッチ配布が一般的であり、単一ファイル化すると差分更新が難しくなる場合があります。

オフライン配布では更新頻度が低いことが多いため、単一ファイル化のメリットがより大きくなります。

配布形態に応じて、単一ファイル化のメリット・デメリットを考慮し、最適な配布戦略を選択することが重要です。

トラブルシューティング

Unresolved Assembly Referenceの対処法

ILMergeやCostura.Fodyを使ってアセンブリを統合する際に、Unresolved Assembly Referenceというエラーが発生することがあります。

これは、ILMergeが結合対象のアセンブリの依存関係を解決できなかった場合に起こります。

対処法は以下の通りです。

  • 依存DLLのすべてを指定する

結合対象のDLLだけでなく、それらが依存しているDLLもすべてILMergeの入力に含める必要があります。

依存関係が複雑な場合は、ビルド出力フォルダのDLLをすべて指定するか、/libオプションで参照パスを追加して解決を助けます。

  • /libオプションの活用

依存DLLが別フォルダにある場合、/lib:<パス>で検索パスを追加します。

これによりILMergeが依存DLLを見つけやすくなります。

  • 入力ファイルの順序を正しくする

メインの実行ファイル(EXE)を最初に指定し、その後に依存DLLを列挙します。

順序が逆だと依存解決に失敗することがあります。

  • ターゲットフレームワークの整合性を確認

結合するアセンブリが同じ.NET Frameworkバージョン向けであるか確認してください。

異なるバージョンのアセンブリを混在させると解決できない場合があります。

  • ILMergeのバージョンを最新にする

古いバージョンのILMergeは依存解決に問題があることがあるため、最新版を利用してください。

Duplicate Typeエラー回避策

Duplicate Typeエラーは、ILMergeで複数のアセンブリに同じ名前空間・クラス名の型が存在し、それらが衝突した場合に発生します。

これにより結合が失敗します。

回避策は以下の通りです。

  • /internalizeオプションを使う

ILMergeの/internalizeオプションを指定すると、結合後のDLLの公開型をinternalに変更し、外部からのアクセスを制限します。

これにより名前の衝突を防げます。

  • 名前空間の整理

可能であれば、ソースコードレベルで名前空間やクラス名を整理し、重複を避けることが根本的な解決になります。

  • 結合対象の見直し

同じ型を含むDLLをすべて結合する必要があるか検討し、不要なDLLを除外するか、別途配布する方法を検討します。

  • ILMergeのバージョンアップ

新しいバージョンでは型の衝突に関する処理が改善されている場合があるため、最新版を利用してください。

大容量バイナリでのOutOfMemory

ILMergeで非常に大きなアセンブリや多数のDLLを結合しようとすると、OutOfMemoryExceptionが発生することがあります。

これはILMergeがメモリ上でILコードを処理するため、メモリ不足に陥るためです。

対処法は以下の通りです。

  • 64ビット版ILMergeを使う

32ビット版ILMergeはメモリ制限が低いため、64ビット版を利用してメモリ上限を拡大します。

ILMergeの64ビット版は公式サイトやNuGetで入手可能です。

  • 結合対象を分割する

一度に大量のDLLを結合せず、複数回に分けて段階的に結合する方法があります。

例えば、関連するDLLをグループ化して結合し、最後にそれらをまとめる方法です。

  • 不要なDLLを除外する

埋め込みが不要なDLLを除外し、結合対象を最小限に抑えます。

  • メモリ使用量の監視と環境の見直し

実行環境のメモリ容量を増やすか、他のメモリ消費プロセスを減らしてILMergeに割り当てるメモリを確保します。

起動遅延が発生したときの分析方法

Costura.Fodyなどの埋め込み型ツールを使うと、実行時にDLLの展開処理が発生するため、起動遅延が起こることがあります。

遅延の原因を特定し、改善するための分析方法は以下の通りです。

  • プロファイリングツールの利用

Visual Studioの診断ツールやJetBrains dotTraceなどで起動時のCPU使用率やメソッド呼び出し時間を計測し、どの処理が遅延の原因か特定します。

  • ログ出力の追加

アプリケーションの起動処理にログを追加し、DLLの展開開始・終了時刻を記録します。

これにより、どのDLLの展開に時間がかかっているかがわかります。

  • AssemblyResolveイベントの監視

Costura.FodyはAssemblyResolveイベントでDLLを展開するため、このイベントの発生回数や処理時間を計測します。

頻繁に発生している場合は、DLLの分割や読み込み順序の見直しが必要です。

  • 不要なDLLの除外

埋め込み対象のDLLを減らすことで、展開処理の負荷を軽減できます。

FodyWeavers.xmlで除外設定を行い、必要最低限のDLLだけを埋め込むようにします。

  • 起動時のプリロード設定

Costura.FodyのPreloadOrderオプションを使い、依存関係のあるDLLを先に読み込むことで、遅延を分散させることが可能です。

これらの方法で起動遅延の原因を特定し、適切な対策を講じることで、ユーザー体験の向上につなげられます。

まとめ

ILMergeとCostura.Fodyを使ったDLLの単一ファイル化は、配布の簡素化や依存関係管理の改善に役立ちます。

ILMergeは.NET Framework向けで結合型、起動速度が速い一方、Costura.Fodyは幅広い環境対応の埋め込み型で導入が簡単です。

各ツールの特徴や注意点、トラブル対処法を理解し、プロジェクトの要件に合わせて適切に選択・運用することが重要です。

関連記事

Back to top button