.NET Winform 将引用的dll文件集成到exe中(转)

Winform程序经常需要引用一些第三方dll文件,这些dll在发布后与exe文件保存在同一目录下,虽然将dll文件集成到exe中会增大文件尺寸,但程序目录会相对整洁。

下面介绍一种比较简单的集成方法和注意事项。

第一步,将需要引用的dll文件复制到项目中

您可以:1.复制到项目根目录;2.复制到某个文件夹中。

此处以将dll复制到"lib"文件夹为例。

.NET Winform 将引用的dll文件集成到exe中 1.png

将要引用的dll文件复制到"lib"文件夹中


第二步,引用复制到项目中的dll文件

右键点击"引用"或项目名称,选择"添加引用(F)..."

.NET Winform 将引用的dll文件集成到exe中 2.png

切换至在“添加引用”对话框中的“浏览”选项卡,选择项目目录中刚刚复制过来的dll文件。

.NET Winform 将引用的dll文件集成到exe中 3.png


第三步,设置引用项的属性为“复制到输出目录”为“不复制”

右键点击“引用”文件夹中刚刚完成添加引用的项目,并点击“属性”

.NET Winform 将引用的dll文件集成到exe中 4.png

将“属性页”中的“复制本地”项改为“False”。

.NET Winform 将引用的dll文件集成到exe中 5.png


第四步,设置之前复制到项目中的dll文件属性

右键点击最开始复制到项目目录中的dll文件,点击“属性”。

.NET Winform 将引用的dll文件集成到exe中 6.png

将“属性”页中的“复制到输出目录”设置为“不复制”,“生成操作”设置为“嵌入的资源”。

.NET Winform 将引用的dll文件集成到exe中 7.png


至此,所有的文件和引用设置就结束了,下面是最后的关键一步:

第五步,在program.cs中添加加载文件代码

由于文件被集成到exe中,不会被自动加载,所以需要在这里告诉程序在加载失败时加载集成在exe中的dll文件。

在Program.cs中添加下面高亮部分代码,目的是在程序集解析失败时(由于我们设置不将dll复制到根目录,所以此处的解析失败自然就是找不到引用的dll文件),告诉程序加载已经集成到exe中的dll。

这里要注意设置dll文件前缀(下面示例代码中的[resourceName]变量):集成到项目中的文件,在原始文件名之前会自动加入【程序集名称】和【文件夹名】,见下方用Reflector工具打开的exe文件中的资源文件,像这样:“[程序集名称].[文件夹名].[原始文件名]”。

如果dll文件是复制到根目录,那么集成后的文件名就是:“[程序集名称].[原始文件名]”。

如果dll文件是复制到dll目录,那么集成后的文件名就是:“[程序集名称].dll.[原始文件名]”。

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Reflection;
namespace ProxySniffer
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            //用于加载引用的dll资源
            AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
            {
                String resourceName = "ProxySniffer.lib." new AssemblyName(args.Name).Name + ".dll";
                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
                {
                    Byte[] assemblyData = new Byte[stream.Length];
                    stream.Read(assemblyData, 0, assemblyData.Length);
                    return Assembly.Load(assemblyData);
                }
            };
 
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
}

使用Reflector打开exe文件查看内部资源就一目了然了,这个各位可以自己确认总结规律:

.NET Winform 将引用的dll文件集成到exe中 8.png

程序集名称,还可以使用以下方式获取:

1
Assembly.GetExecutingAssembly().GetName().Name

最后,重新发布程序,exe变大,同目录下的dll文件也消失了。

原文地址:https://www.cnblogs.com/lip-blog/p/7365942.html