C#将dll打包到exe里

教程及坑。

首先按照网上的教程操作嵌入dll。(教程来源:https://blog.csdn.net/xiaoid/article/details/93598438

1、 引用dll,将引用的dll设置为不复制(是否复制不影响使用,编译完成后,只需要exe就可以了, 旁边的dll是否存在并不影响使用)。

2、 将引用的dll嵌入到项目中。

新建一个项目文件夹(例如libs),将引用的dll复制到此文件夹中,并包含中项目里,设置为“嵌入的资源”

3、在Program.cs里的main()方法中,添加代码,处理找不到dll的相关异常处理。

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
    //加载dll
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    //Application.Run(new Form1());
    BeginRun();
 
}
//主窗体不是.net标准库的Form对象,遇到新的问题,一开始执行程序就提示找不到dll的错误,通过设置断点发现,项目在开始执行main()时,还没进入main()中的代码,直接提示找不到dll。
//经过查询资料、多次测试,猜测是在执行main()的时候,提前检测main()内的代码使用的引用资源,而不是执行到该行代码时才检查相关引用资源,于是在main中调用另一个func避开检测。(此文章段来自本文章开头的教程)
static void BeginRun()
{
    var _form1 = new Form1();
    Application.Run(_form1);

}

//加载嵌入资源的dll方法,有坑,请看我的修改版
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs e)
{
    //项目的命名空间为myapp, 嵌入dll资源在libs文件夹下,所以这里用的命名空间为: myapp.libs.
    string _resName = "myapp.libs." + new AssemblyName(e.Name).Name + ".dll";
    using (var _stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(_resName))
    {
        byte[] _data = new byte[_stream.Length];
        _stream.Read(_data, 0, _data.Length);
        return Assembly.Load(_data);
    }
}

//加载dll方法,修改版
//教程原来的方法中,string _resName = "myapp.libs." + new AssemblyName(e.Name).Name + ".dll"; 其中new AssemblyName(e.Name).Name获取不到资源名,打断点调试后,发现e里面包含我们需要的dll,所以通过Name属性去获取我们的dll名称。
 private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs e)
        {
            //项目的命名空间为myapp, 嵌入dll资源在libs文件夹下,所以这里用的命名空间为: myapp.libs.
            string dllName = e.Name.Contains(",") ? e.Name.Substring(0, e.Name.IndexOf(',')) : e.Name.Replace(".dll", "");
//这里dllName去判断了一下名称,根据需要修改命名空间,可以打断点找到,去掉下面的这个if也可以,调试时可能会有异常抛出,但是不影响程序,正式打包后不会有报错
            if (dllName != "myapp.resources")
            {
                string _resName = "FastMC.Resources." + dllName + ".dll";
                using (var _stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(_resName))
                {
                    byte[] _data = new byte[_stream.Length];
                    _stream.Read(_data, 0, _data.Length);
                    return Assembly.Load(_data);
                }
            }
            return null;
        }

相关推荐

微信扫一扫,分享到朋友圈

C#将dll打包到exe里
返回顶部

显示

忘记密码?

显示

显示

获取验证码

Close