参考自:http://www.digitallycreated.net/Blog/61/combining-multiple-assemblies-into-a-single-exe-for-a-wpf-application
https://stackoverflow.com/questions/1025843/merging-dlls-into-a-single-exe-with-wpf
在WPF中,将dll作为嵌入的资源打包到exe中的步骤:
注:该方法不能将非C#类型的dll(比如:C++编译的dll)打包到exe
第一步:添加以下代码段到WPF项目的.csproj文件中(需添加到节点“Import”的后面)。个人理解这段代码的作用:设置项目引用的dll为嵌入的资源(经测试,单独手动设置dll为嵌入的资源无效,必须添加这段代码到项目文件中,且需在节点“Import”的后面)
<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,可以新建一个)
public 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