C#将引用的dll嵌入到exe文件中

当发布的程序有引用其它dll, 又只想发布一个exe时就需要把dll打包到exe

当然有多种方法可以打包, 比如微软的ILMerge,混淆器附带的打包...

用代码打包的实现方式也有很好,本文只是其中一种实现方式,不需要释放文件!.

方法如下:

1.项目下新建文件夹dll

2.把要打包的dll文件放在dll文件夹下,并包括在项目中

3.右键文件属性, 生成操作选择嵌入的资源

4.实现如下代码, 在窗口构造中实现也可以(在窗体事件中无效,如winform_load)

这里需要注意,“引用”下的dll,需要设置“复制本地”为False,这样在bin目录下生成exe的时候就不会顺便复制dll了(这步可要可不要)

using System;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;using System.Windows.Forms;
using System.Reflection;
namespace WindowsFormsApplication13{    static class Program    {        /// <summary>        /// 应用程序的主入口点。        /// </summary>        [STAThread]        static void Main()        {            AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;            //Application.EnableVisualStyles();           // Application.SetCompatibleTextRenderingDefault(false);
            Application.EnableVisualStyles();            Application.SetCompatibleTextRenderingDefault(false);            Application.Run(new Form1());        }
        private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)        {            string resourceName = "WindowsFormsApplication13.dll." + 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);            }        }    }}

实现原理:

把dll嵌入到exe程序的资源中,  

并实现程序集加载失败事件(当在程序目录和系统目录下找不到程序集触发),

当找不到程序集时就从资源文件加载, 先转换为字节数组再转换到程序集返回给程序,

这样dll就被加载到程序中了.

如果exe所在文件夹下有相应dll, 事件并不会被触发!