参考:https://blog.csdn.net/m0_37862405/article/details/81532077
在WPF中,将dll作为嵌入的资源打包到exe中的步骤:
注:该方法不能将非C#类型的dll(比如:C++编译的dll)打包到exe
添加以下代码段到WPF项目的.csproj文件中(需添加到节点“Import”的后面)。个人理解这段代码的作用:设置项目引用的dll为嵌入的资源(经测试,单独手动设置dll为嵌入的资源无效,必须添加这段代码到项目文件中,且需在节点“Import”的后面)
1
2
3
4
5
6
7<Target Name="AfterResolveReferences">
<ItemGroup>
<EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
<LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
</EmbeddedResource>
</ItemGroup>
</Target>添加以下代码到Program.cs(若没有Program.cs,可以新建一个)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39public class Program
{
/// <summary>
/// 使用静态构造函数来绑定解析程序集失败事件
/// </summary>
static Program()
{
AppDomain.CurrentDomain.AssemblyResolve += OnResolveAssembly;
}
[STAThreadAttribute]
public static void Main()
{
App.Main(); //启动WPF项目
}
//解析程序集失败,会加载对应的程序集
private static Assembly OnResolveAssembly(object sender, ResolveEventArgs args)
{
Assembly executingAssembly = Assembly.GetExecutingAssembly();
AssemblyName assemblyName = new AssemblyName(args.Name);
var path = assemblyName.Name + ".dll";
//判断程序集的区域性
if (!assemblyName.CultureInfo.Equals(CultureInfo.InvariantCulture))
{
path = string.Format(@"{0}\{1}", assemblyName.CultureInfo, path);
}
using (Stream stream = executingAssembly.GetManifestResourceStream(path))
{
if (stream == null) return null;
var assemblyRawBytes = new byte[stream.Length];
stream.Read(assemblyRawBytes, 0, assemblyRawBytes.Length);
return Assembly.Load(assemblyRawBytes);
}
}
}在项目属性中,修改项目的启动对象为Program.cs