
教程及坑。
首先按照网上的教程操作嵌入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;
}
