引言
在部署 C# 桌面应用(如 WinForms、WPF 或控制台程序)时,我们常常面对一堆 .dll 文件------这不仅影响用户体验,还容易导致依赖丢失或版本混乱。有没有一种简单、自动化的方式,把所有依赖"藏"进主程序里?
答案是:Fody.Costura。
本文将手把手教你如何通过 NuGet 安装 Fody.Costura,并配置项目,最终生成一个完全自包含的单一 EXE 文件。
一、什么是 Fody 和 Costura?
Fody:一个开源的 .NET 编译时 IL(中间语言)织入框架,允许在编译阶段修改程序集。
Costura:Fody 的一个插件,专门用于将项目引用的所有程序集(包括 NuGet 包生成的 DLL)嵌入到主 EXE 中,并在运行时自动解压加载。
✅ 优点:配置简单,几乎零代码
支持 .NET Framework 4.0+ 和 .NET Core/.NET 5+(需注意兼容性)
自动处理 PDB(调试符号)和 XML 文档
开源、社区活跃(GitHub 超 6k stars)
二、操作流程(Visual Studio)
步骤 1:创建或打开你的 C# 项目
确保你有一个可正常编译运行的项目,例如:
控制台应用(Console App)
WinForms 应用
WPF 应用
⚠️ 注意:不适用于 ASP.NET Web 项目(因 IIS 加载机制不同)。
步骤 2:通过 NuGet 安装 Fody 和 Costura
在 Visual Studio 中:
右键点击你的项目 → "管理 NuGet 程序包"
切换到 "浏览" 选项卡
搜索并安装包:Fody.Costura
💡 实际上,安装 Fody.Costura 会自动依赖并安装 Fody,但建议确认两者都已正确安装。
安装完成后,你会看到项目根目录下多出一个文件:FodyWeavers.xml。


步骤 3:检查并配置 FodyWeavers.xml
打开 FodyWeavers.xml,内容应类似:
csharp
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura />
</Weavers>
这就是启用 Costura 的标志。默认配置已足够大多数场景使用。
常见可选配置(按需添加):
csharp
<Costura
IncludeDebugSymbols="true" <!-- 是否嵌入 PDB -->
DisableCompression="false" <!-- 是否压缩嵌入的 DLL(默认压缩) -->
CreateTemporaryAssemblies="false" <!-- 是否在磁盘生成临时 DLL(默认不生成) -->
Unmanaged64Assemblies="NativeLib64" <!-- 指定 64 位非托管 DLL 嵌入名 -->
Unmanaged32Assemblies="NativeLib32" <!-- 指定 32 位非托管 DLL -->
/>
📌 提示:一般保持默认即可,除非你有特殊需求(如需要调试符号)。
步骤 4:重新编译项目
清理解决方案(Build → Clean Solution)
重新生成(Build → Rebuild Solution)
编译成功后,进入输出目录(通常是 bin\Debug\netX.X 或 bin\Release\netX.X),你会发现:
主 EXE 文件依然存在(如 MyApp.exe)
所有原本的 .dll 文件不见了!
但程序仍能正常运行!
这是因为 Costura 已将所有依赖 DLL 作为资源嵌入到了 EXE 中,并在程序启动时通过 AppDomain.CurrentDomain.AssemblyResolve 事件动态加载。
步骤 5:验证是否成功合并
你可以用以下方式验证:
方法 A:直接运行 EXE
将 MyApp.exe 复制到一个空文件夹中,双击运行。如果程序正常启动,说明合并成功。
方法 B:使用反编译工具查看资源
用 ILSpy 或 dnSpy 打开 EXE,展开 "Resources",你会看到类似:
csharp
costura.system.windows.forms.dll
costura.newtonsoft.json.dll
这些就是被嵌入的依赖项。
三、高级技巧与注意事项
1. 排除某些 DLL 不合并
如果你希望某些 DLL 不被嵌入(例如插件或需外部更新的模块),可在项目文件中添加:
csharp
<ItemGroup>
<Reference Include="SomeExternalLib">
<Private>false</Private>
<CopyLocal>false</CopyLocal>
</Reference>
</ItemGroup>
或者在引用上右键 → 属性 → 将 "复制本地" 设为 False。
2. 支持非托管 DLL(如 C++ 编写的 .dll)
Costura 也支持嵌入非托管 DLL(native DLL),但需手动指定名称:
csharp
<Costura
Unmanaged32Assemblies="mylib_x86"
Unmanaged64Assemblies="mylib_x64" />
并将你的 mylib_x86.dll 和 mylib_x64.dll 设置为 "嵌入的资源"(Build Action = Embedded Resource)。
3. 调试时仍能看到 PDB?
默认情况下,Debug 模式会嵌入 PDB,Release 模式不会。可通过 IncludeDebugSymbols="true" 强制包含。
四、总结
通过 Fody.Costura,我们只需两步(安装 NuGet + 编译),就能将整个 C# 应用打包成一个干净、独立的 EXE 文件,极大简化部署和分发流程。
✅ 核心优势:零代码侵入、全自动、兼容性强
赶快在你的项目中试试吧!