三种方法,让WPF项目生成单文件

Posted lonelyxmas

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三种方法,让WPF项目生成单文件相关的知识,希望对你有一定的参考价值。

原文:三种方法,让WPF项目生成单文件

在使用WPF写一些小工具时,往往需要将多个DLL文件嵌入到EXE文件里,生成单文件。这里介绍三种方案:

  • 把DLL文件作为嵌入资源
  • 使用Costura.Fody
  • 使用.NET Reactor。

一、把DLL文件转换为嵌入资源

第一步,在项目中新建Resources文件夹,把需要的dll文件拷贝到该目录中(可以是多个dll文件),然后修改每个文件的属性,将生成操作改为嵌入的资源,例如:

技术图片
拷贝dll文件
技术图片
修改生成操作

第二步,修改App.xaml.cs文件,添加程序集解析失败事件,并加载指定的嵌入资源。修改后内容为:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Configuration;
  4. using System.Data;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Reflection;
  8. using System.Threading.Tasks;
  9. using System.Windows;
  10. namespace Embed
  11. {
  12. /// <summary>
  13. /// App.xaml 的交互逻辑
  14. /// </summary>
  15. public partial class App : Application
  16. {
  17. readonly string[] dlls = new string[] { "Newtonsoft.Json" }; // 去掉后缀名
  18. public App()
  19. {
  20. AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
  21. }
  22. private System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
  23. {
  24. string resources = null;
  25. foreach (var item in dlls)
  26. {
  27. if (args.Name.StartsWith(item))
  28. {
  29. resources = item + ".dll";
  30. break;
  31. }
  32. }
  33. if (string.IsNullOrEmpty(resources)) return null;
  34. var assembly = Assembly.GetExecutingAssembly();
  35. resources = assembly.GetManifestResourceNames().FirstOrDefault(s => s.EndsWith(resources));
  36. if (string.IsNullOrEmpty(resources)) return null;
  37. using (Stream stream = assembly.GetManifestResourceStream(resources))
  38. {
  39. if (stream == null) return null;
  40. var block = new byte[stream.Length];
  41. stream.Read(block, 0, block.Length);
  42. return Assembly.Load(block);
  43. }
  44. }
  45. }
  46. }

其中dlls数组内容为Resources目录下去掉后缀的文件名。比如Resources目录下有Newtonsoft.Json.dllMaterialDesignThemes.Wpf.dllMaterialDesignColors.dll,则dlls数组内容为

readonly string[] dlls = new string[] { "Newtonsoft.Json" , "MaterialDesignThemes.Wpf" , "MaterialDesignColors"}; 

最后重新生成项目,删除生成目录下的dll文件即可。

二、使用Costura.Fody

Costura.Fody可以把引用的库文件嵌入为资源,使用起来非常简单,直接安装Costura.Fody即可:

PM> Install-Package Costura.Fody

举一个简单例子:

  1. 新建一个WPF项目,添加Newtonsoft.Json:PM> Install-Package Newtonsoft.Json
  2. 安装Costura.Fody
  3. 生成项目

生成结果如下:

技术图片
Costura.Fody生成结果
Costura.Fody链接:https://github.com/Fody/Costura

三、使用 .NET Reactor

.NET Reactor是一款.NET代码加密混淆工具,同时具有扫描依赖,并嵌入程序集的功能。
具体使用步骤:

  1. 打开WPF项目生成的exe文件
  2. 点击扫描依赖项按钮;
  3. 勾选嵌入所有程序集;
  4. 点击保护即可。
    技术图片
    使用流程
    生成结果如下:
    技术图片
    生成结果

总的来说,上面三种方式都可以嵌入dll资源,生成单文件。Costura.Fody和.NET Reactor使用起来方便,改动最小。如果还有加密需求,那就推荐使用.NET Reactor。

版权声明:本文为「txfly」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://www.jianshu.com/p/72534a7e2f4a

以上是关于三种方法,让WPF项目生成单文件的主要内容,如果未能解决你的问题,请参考以下文章

WPF 基于 .NET 5 框架和 .NET 6 的 SDK 进行完全单文件发布

WPF 基于 .NET 5 框架和 .NET 6 的 SDK 进行完全单文件发布

WPF 基于 .NET 5 框架和 .NET 6 的 SDK 进行完全单文件发布

c# wpf项目中引用的dll怎么让它能自动更新?

更改 WPF 项目模板的命名空间

JavaScript 有用的代码片段和 trick