You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将指定关联DLL与C# WinForms程序合并为单个EXE?

问题

我有一个包含两个C#项目的解决方案:一个WinForms应用程序(exe)和一个类库(dll),同时引用了多个外部DLL。希望将自有项目的输出合并为单个exe文件,同时保留其他外部DLL独立存在,文件结构变化如下:

原结构:

  • myApp.exe
  • myLib.dll
  • externalLib1.dll
  • externalLib2.dll
  • ...

目标结构:

  • myMergedAppAndLib.exe
  • externalLib1.dll
  • externalLib2.dll
  • ...

已知限制:

  • ILMerge已被弃用,不确定是否支持只合并自有项目而排除外部DLL
  • Visual Studio的“生成单个文件”发布选项会合并所有外部DLL,不符合需求
  • 无法合并两个自有项目,因为该类库还要给第三个WinForms项目使用

可行方案

完全可以实现需求,以下是几种实用的实现方式:

方法1:使用ILRepack(ILMerge的开源替代工具)

ILRepack是专门用于合并.NET程序集的开源工具,支持选择性合并指定程序集,完美匹配你的需求。

操作步骤:

  1. 安装工具:可以通过NuGet安装ILRepack包,或者直接下载ILRepack可执行文件
  2. 执行合并命令:
    直接指定仅合并自有项目的exe和dll,未提及的外部DLL会自动保留为独立文件:
    ILRepack /out:myMergedAppAndLib.exe myApp.exe myLib.dll
    
    也可以显式排除外部DLL(避免误合并):
    ILRepack /out:myMergedAppAndLib.exe myApp.exe myLib.dll /exclude:externalLib1.dll /exclude:externalLib2.dll
    
  3. 执行完成后,输出目录会生成myMergedAppAndLib.exe,外部DLL保持独立存在。

方法2:将类库嵌入为资源并手动加载

把myLib.dll作为嵌入资源打包进WinForms项目,程序启动时从资源中加载该类库,无需依赖外部的myLib.dll文件。

操作步骤:

  1. 在WinForms项目中添加对myLib.dll的引用,将引用的复制本地属性设置为False
  2. 将myLib.dll文件添加到WinForms项目中,设置其生成操作为嵌入的资源
  3. 在Program.cs的入口方法前添加程序集解析逻辑:
    using System.Reflection;
    
    [STAThread]
    static void Main()
    {
        // 注册程序集解析事件,按需从嵌入资源加载myLib
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
        {
            var assemblyName = new AssemblyName(args.Name).Name + ".dll";
            // 替换为你的WinForms项目实际命名空间
            var resourceName = $"YourWinFormsNamespace.{assemblyName}";
            
            using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
            {
                if (stream == null) return null;
                var assemblyBytes = new byte[stream.Length];
                stream.Read(assemblyBytes, 0, assemblyBytes.Length);
                return Assembly.Load(assemblyBytes);
            }
        };
    
        Application.SetHighDpiMode(HighDpiMode.SystemAware);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
    
  4. 编译后生成的exe已包含myLib.dll的内容,外部DLL仍保持独立。

方法3:通过MSBuild任务自动合并

在WinForms项目的.csproj文件中添加MSBuild任务,实现编译完成后自动执行合并,无需手动操作命令行。

操作步骤:

  1. 通过NuGet安装ILRepack.MSBuild.Task包
  2. 编辑WinForms项目的.csproj文件,添加以下配置:
    <Target Name="ILRepack" AfterTargets="Build">
      <ItemGroup>
        <InputAssemblies Include="$(OutputPath)myApp.exe" />
        <InputAssemblies Include="$(OutputPath)myLib.dll" />
      </ItemGroup>
      <ILRepack
        OutputFile="$(OutputPath)myMergedAppAndLib.exe"
        InputAssemblies="@(InputAssemblies)"
        CopyDependencies="false" <!-- 不复制外部依赖,保留独立文件 -->
        AllowDuplicateResources="true"
        />
    </Target>
    
  3. 编译项目时,会自动在输出目录生成合并后的exe文件。

内容的提问来源于stack exchange,提问作者Thomas853

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 13:55:21