為了讓小工具部署更輕鬆 (單一 EXE 檔),常需將相依的第三方 DLL 內嵌。本文介紹三種主流做法並比較優劣。
Embedded Resource。
Program.cs 靜態建構函式中讀取資源串流寫入檔案:private static void ExtractResourceToFile(string resourceName, string filename)
{
if (!File.Exists(filename))
using (Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
using (FileStream fs = new FileStream(filename, FileMode.Create))
{
byte[] b = new byte[s.Length];
s.Read(b, 0, b.Length);
fs.Write(b, 0, b.Length);
}
}
static Program()
{
ExtractResourceToFile("EmbeddedDLL2ExeDemo.ThirdPartyDllDemo.dll", "ThirdPartyDllDemo.dll");
}
缺點: 執行目錄會產生實體 DLL 檔,不夠乾淨;啟動稍慢。
ILMerge 是微軟官方工具,可將多個 .NET 組件合併為單一組件,執行時直接從資源載入,不寫入磁碟。
ilmerge EmbeddedDLL2ExeDemo.exe ThirdPartyDllDemo.dll /ndebug /out:EmbeddedDLL2ExeDemo.exe
/ndebug 移除偵錯資訊;/out 指定輸出檔名。優點: 真正單一檔案部署,無臨時檔案,效能最佳。
缺點: 不支援含非受控程式碼的混合模式組件;部分參數 (如 /ver) 在某些版本失效。
多數商業/開源混淆器 (如 ConfuserEx, Dotfuscator, SmartAssembly) 皆提供「合併組件」選項,操作介面友善,適合已引入混淆流程的專案。
| 方法 | 部署乾淨度 | 效能 | 適用場景 | 限制 |
|---|---|---|---|---|
| 資源釋放 | 產生臨時檔 | 啟動較慢 | 快速原型、混合模式 DLL | 需寫入磁碟權限 |
| ILMerge | 純單一檔案 | 最佳 | 純 .NET 組件、自動化建置 | 不支援非受控代碼 |
| 混淆器 | 純單一檔案 | 佳 | 已有混淆需求的專案 | 需額外授權/學習成本 |
建議優先評估 ILMerge,若組件包含非受控代碼則退而求其次使用資源釋放法。