Winformやwpfの開発では多くのサードパーティ製DLLが使われますが、パッケージ化するたびにDebugディレクトリ内のファイルを顧客にコピーするか共有する必要があり、使い方があまり便利ではありません。 以前にILMergeやEnigma Virtual Boxなど、dllファイルをマージするソフトをいくつか試しましたが、「Costura.Fody」を知るまでは、世界の方がずっと良いと感じていました~
以下はWinformによって書かれたプログラムで、「HttpHelper.dll」と「Newtonsoft.Json.dll」という2つのDLLを参照しています。プログラムを生成する際には、exeファイルとこの2つのDLLファイルが入り、非常に不快感を覚えます。もしDLLが1つ減ると、下図のように例外を報告することがあります。
以下のリンクは以前の使用例です(推奨されません)
Costura.Fodyツールを使えば、元のDLLをターゲットのEXEにマージできます
プロジェクトホームページ:https://github.com/Fody/Costura
使い方、直接Nugetパッケージをインストールする方法:
Costura.fodyを正常に追加すると、ソリューションは自動的にFodyWeavers.xmlファイルを追加します。
解決策を再生成すれば、プログラム生成ディレクトリで成功が確認でき、すべてのDLLが完全にexeに統合され、exeファイルをクライアントに直接コピーして独立して実行できます。 以下に示すように:
1>------ すべての再構築が開始されました:プロジェクト:itsvse、構成:デバッグ 任意のCPU------ 1> Fody: Fody(バージョン2.0.0.0)実行中 1> フォディ/コストゥラ:「Costura.dll」に関する言及は見つかりません。 参考文献は修正されていません。 1> フォディ/コストゥラ:埋め込み 'E:\project\itsvse\itsvse\HttpHelper.dll' 1> フォディ/コストゥラ:埋め込み「E:\project\itsvse\itsvse\Newtonsoft.Json.dll」 1> フォディ:609msで終えました。 1> Fody:設定上無効化されているためアセンブリ検証をスキップしました 1> Fody:検証を3msで完了。 1> itsvse -> E:\project\itsvse\itsvse\bin\Debug\itsvse.exe ========== 全て再生:1人が成功、0が失敗、0==========スキップ
上の画像からもわかるように、生成されたファイルにはNewtonsoft.Json.dll、HttpHelper.dll、Costura.dllは生成されず、2つのファイルのみが生成されており、エラーなしで直接実行itsvse.exe可能です! (PDBファイルは削除可能です。)
ILSpyツールを使ってプログラムをデコンパイルし、下の図のように生成されたソースコードを見ていきましょう。
実装原則の紹介
CLRがアセンブリの読み込みを試みるが読み込めない場合、AppDomain.AssemblyResolveイベントを発生させます。 プログラムはこのイベントを受信し、CLRがロードしようとしているアセンブリをイベントハンドラに返すことで、プログラムは通常通り動作を続けられます。
Fody.Costuraは、プロジェクト構築時にEXEが参照したすべてのDLLをEXEファイルに埋め込みます。 実行中にプログラムがこれらのDLLのいずれかを使用すると(CLRがDLLファイルを見つけられないためAppDomain.AssemblyResolveイベントがトリガーされます)、必要なDLLはEXEファイルの埋め込みリソースから抽出されます。
AttachメソッドはAppDomain.AssemblyResolveイベントを受信しているのがわかります。 CLRがアセンブリのロードに失敗した場合、AssemblyResolveイベントハンドラが実行されます。 AssemblyResolveは、Common.ReadFromEmbeddedResourcesメソッドを通じて、ロードされたアセンブリの埋め込みリソースからターゲットアセンブリを取得し、CLRに戻します。
これを見て、Attachメソッドはいつ実装されたのか疑問に思うかもしれません。
実際、C#言語の場合、CLRは大きな裏技を隠しています。CLRは各モジュール(各アセンブリは1つ以上のモジュールを含む)をロードする前に初期化されたコードを実行することができるのです。 残念ながら、C#言語はこの部分のコードを制御できません。 Fody.CosturaはILコードをEXEアセンブリの内部モジュールの初期化関数に直接注入し、このILコードの部分が実際にAtchメソッドを実行します。 この方法により、EXEアセンブリが読み込まれた後、Attachメソッドを即座に呼び出すことができます。
上記はFody.Costuraの実装原則の簡単な紹介です。
高度な構成
これらの構成はCosturaFodyWeavers.xmlファイルで追加または変更されます。
CreateTemporaryAssemblies デフォルト:false これにより、埋め込みファイルをディスクに埋め込み、その後メモリに読み込みます。 これは、物理ファイルからアセンブリを読み込みたい特定の状況で有用です。
IncludeDebugSymbols デフォルト:trueです 参照アセンブリの.pdbsも埋め込まれているかどうかを制御します。
DisableCompression デフォルト:false 組み込みアセンブリはデフォルトで圧縮され、ロード時には非圧縮されます。 このオプションで圧縮をオフにできます。 注意:非標準DLLや暗号化DLLを参照する際は、このプロパティを必ずオフにしてください。 そうしないと、実行ファイルが開けなくなる状況になります。 これは私がDSkin.dllを使っていたときに発見されました。
DisableCleanup デフォルト:false Costuraの一部として、組み込みコンポーネントはビルドに含まれていません。 このクリーンアップはオフにできます。
LoadAtModuleInit デフォルト:trueです Costuraはモジュール初期化の一環としてデフォルトでロードされます。 フラグがその行動を無効化します。 CosturaUtility.Initialize()をどこかで使えるか確認してください。
アセンブリー排除 使い方:ExcludeAssemblies="DLL1|DLL2」 「すべてのコピーローカル参照を埋め込む」というデフォルトアクションから除外するアセンブリ名のリスト。
アセンブリーを含める 使い方:IncludeAssemblies="DLL1|DLL2」 デフォルトのアクション「すべてのコピーローカル参照を埋め込む」に含まれるアセンブリ名のリスト。
Unmanaged32Assemblies&Unmanaged64Assemblies 使い方:Unmanaged32Assemblies="DLL1|DLL2" Unmanaged64Assemblies="DLL1|DLL2」 混合モードアセンブリはマネージドアセンブリと同じ方法でロードすることはできません。 したがって、Costuraがどのコンポーネントが混合モードで、どの環境で読み込むかを識別しやすくするために、それらの名前を一方または両方のリストに含めるべきです。 名前に.exeや.dllを含めないでください。
プリロードオーダー 使用例:PreloadOrder="DLL1|DLL2」 地元の図書館はCosturaによって自動的に読み込み可能です。 ローカルライブラリを含めるには、ライブラリの不安定性に応じてcastura32またはcostura64という組み込みリソースとしてプロジェクトに組み込みます。 あるいは、プリロードされたライブラリの読み込み順を指定することもできます。 ディスクから一時的なコンポーネントを混ぜると、それらもプリロードされています。
CosturaUtility(コストラ・ユーティリティ) 使い方:
CosturaUtilityは、自分のコードでCosturaシステムを手動で初期化できるクラスです。これは主にモジュール初期化プログラムが動作しない場合のためですライブラリやモノなどです。
最後に、本文のソースコードをダウンロードしてください:
観光客の皆さん、この投稿の隠された内容を見たい方は、どうぞ 答える
|