可以,但仅限于.NET Framework项目;它将托管DLL作为资源嵌入并在运行时动态解包加载,不支持.NET Core/5+、本机DLL及间接依赖。

Costura.Fody 能不能真正把所有 DLL 打进 EXE?
可以,但仅限于 .NET Framework 项目(.NET Core / .NET 5+ 不支持)。Costura.Fody 在编译时把引用的 dll 作为资源嵌入到主程序集(EXE 或 DLL)中,并在运行时用 AppDomain.CurrentDomain.AssemblyResolve 动态解包加载。它不修改 IL、不混淆、不合并类型,只是“打包 + 延迟加载”。
常见误解是“打完就完全独立”,实际仍需目标机器装对应 .NET Framework 运行时(如 v4.7.2),且无法处理本机依赖(如 SQLite.Interop.dll、libuv.dll 等非托管 DLL)——这些必须手动配置或改用其他方案。
如何正确安装并启用 Costura.Fody
在 Visual Studio 中,通过 NuGet 安装 Costura.Fody 即可(注意:不是 Fody 单独包,而是带完整依赖的元包)。安装后会自动生成 FodyWeavers.xml 文件,无需手动编辑,除非你要定制行为。
- 确保项目是
.NET Framework(如net472),右键项目 → 属性 → 目标框架确认 - 不要手动添加
FodyWeavers.xml到项目中;NuGet 安装后它会自动存在且设为AlwaysCopy - 若编译报错
MSB4018: The "FodyTarget" task failed unexpectedly,大概率是 Fody 版本与 Costura 不兼容——降级到Costura.Fody 4.1.0(适配 Fody 6.x)最稳 - 调试时默认不触发内嵌加载(因调试器会提前加载依赖),建议用 Release 模式生成后单独运行 EXE 验证
哪些 DLL 不会被自动内嵌?怎么补救?
Costura 默认只嵌入“项目直接引用”且 Copy Local = True 的托管 DLL。以下情况不会被包含:
- 间接依赖(A 引用 B,B 引用 C,但项目没直接引用 C)→ 在
FodyWeavers.xml中显式声明:<Costura> <IncludeAssemblies>LibraryC</IncludeAssemblies> </Costura>
- 本机 DLL(如
mysql.data.dll依赖的libmysql.dll)→ Costura 不处理,需改用NativeLibs插件,或手动用CosturaConfig设置UnmanagedDlls并配合LoadUnmanagedDlls - 按需加载的插件(如通过
Assembly.LoadFrom("xxx.dll"))→ Costura 无法感知,必须改用资源流加载:Assembly.Load(Properties.Resources.xxx_dll)
替代方案对比:ILMerge vs. Costura vs. .NET 6+ 单文件发布
如果你用的是 .NET Core 3.1 或更新版本(含 .NET 5/6/7/8),根本不用 Costura —— 直接用 SDK 内置单文件发布:
在 .csproj 中加:
<PropertyGroup> <PublishSingleFile>true</PublishSingleFile> <SelfContained>true</SelfContained> <RuntimeIdentifier>win-x64</RuntimeIdentifier> </PropertyGroup>
这会把运行时、依赖、资源全部打包成一个 EXE(可选压缩),且支持本机依赖。而 ILMerge 已停止维护,仅支持旧版 .NET Framework,且不兼容强签名和某些反射场景;Costura 优势在于无感接入、调试友好,但仅限 Framework 生态。
跨平台或新项目,请优先走 SDK 单文件发布;老系统维护或必须跑在客户已装 Framework 的环境里,再考虑 Costura,别混用。










