1. 程式人生 > >C#將DLL嵌入到exe當中

C#將DLL嵌入到exe當中

visual 資源 sse .cn 體積 body [] log sin

原文:C#將DLL嵌入到exe當中

一、將dll文件加入工程

1.找到dll文件

可以在項目的“引用”下找到dll,並且根據屬性中的“路徑”找到文件所在目錄;也可以使用bin目錄下自動生成(其實就是復制)的dll文件
技術分享圖片
這裏需要註意,“引用”下的dll,需要設置“復制本地”為False,這樣在bin目錄下生成exe的時候就不會順便復制dll了(感覺這步可要可不要)。

2.加入工程

可以對著項目(我的即“ShadowSuHelper”)右鍵->添加->現有項;或者更簡單的,復制1中找到的dll,直接在工程中粘貼
技術分享圖片
加入dll後,工程結構如上圖,引用中的還需要保留(否則代碼編譯不通過);此外.dll文件也是必須的(運行時需要調用)。最後,別忘了對剛加入的兩個dll屬性中“生成操作”改為“嵌入的資源”,這樣生成的exe就會嵌入這兩個dll,體積顯著增大,哈哈。

二、添加AssemblyResolve處理函數

添加了AssemblyResolve的處理函數後,當調用dll找不到時,就會回調該函數,我們只需要在這個函數中,將嵌入exe的dll獲取並解析返回即可。這個事件必須在調用dll之前添加,否則就沒用了,這裏我們選擇在Program.cs的Main()方法中設置。
首先引入命名空間
using System.Reflection;
然後在Main方法開頭加入
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

其中的CurrentDomain_AssemblyResolve就是我們的回調函數了,完整代碼如下:

static void Main()
{
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

private static Assembly CurrentDomain_AssemblyResolve(object
sender, ResolveEventArgs args) { string resourceName = "ShadowSuHelper." + new AssemblyName(args.Name).Name + ".dll"; using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName)) { byte[] assemblyData = new byte[stream.Length]; stream.Read(assemblyData, 0, assemblyData.Length); return Assembly.Load(assemblyData); } }

可以在CurrentDomain_AssemblyResolve中設置斷點查看,會發現當程序中首次調用到HtmlAgilityPack.dll或者Newtonsoft.Json.dll的方法時會回調該函數,並且不會再報找不到dll的錯誤了。

C#將DLL嵌入到exe當中