美文网首页.NET
三种方法,让WPF项目生成单文件

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

作者: txfly | 来源:发表于2020-01-13 11:31 被阅读0次

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

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

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

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

    拷贝dll文件 修改生成操作
    第二步,修改App.xaml.cs文件,添加程序集解析失败事件,并加载指定的嵌入资源。修改后内容为:
    using System;
    using System.Collections.Generic;
    using System.Configuration;
    using System.Data;
    using System.IO;
    using System.Linq;
    using System.Reflection;
    using System.Threading.Tasks;
    using System.Windows;
    
    namespace Embed
    {
        /// <summary>
        /// App.xaml 的交互逻辑
        /// </summary>
        public partial class App : Application
        {
            readonly string[] dlls = new string[] { "Newtonsoft.Json" };    // 去掉后缀名
            public App()
            {
                AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
            }
    
            private System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
            {
                string resources = null;
                foreach (var item in dlls)
                {
                    if (args.Name.StartsWith(item))
                    {
                        resources = item + ".dll";
                        break;
                    }
                }
                if (string.IsNullOrEmpty(resources)) return null;
    
                var assembly = Assembly.GetExecutingAssembly();
                resources = assembly.GetManifestResourceNames().FirstOrDefault(s => s.EndsWith(resources));
    
                if (string.IsNullOrEmpty(resources)) return null;
    
                using (Stream stream = assembly.GetManifestResourceStream(resources))
                {
                    if (stream == null) return null;
                    var block = new byte[stream.Length];
                    stream.Read(block, 0, block.Length);
                    return Assembly.Load(block);
                }
            }
        }
    }
    

    其中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项目生成单文件

        本文链接:https://www.haomeiwen.com/subject/bfsgactx.html