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的錯誤了。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com