写在前面
承接篇6。本篇讲 WinForms 应用怎么打包交付给用户:单文件发布、ClickOnce、自动更新、签名。
WinForms 部署比 Web 复杂:你要把 exe + 依赖装到用户机器、管更新、过 SmartScreen。.NET 8 时代,单文件发布 + ClickOnce 是主力,MSIX 是新选择。
一、dotnet publish:单文件发布
.NET SDK 的 dotnet publish 把应用打包成可分发的产物。最实用的是单文件(self-contained exe,用户机器不用装 .NET):
| |
参数:
| 参数 | 含义 |
|---|---|
-c Release | Release 编译 |
-r win-x64 | 目标运行时(Windows 常用 RID 有 win-x64、win-x86、win-arm64) |
--self-contained true | 自包含(带 .NET 运行时,用户免装) |
PublishSingleFile | 打成单个 exe |
IncludeNativeLibrariesForSelfExtract | 原生库也塞进单文件 |
| |
自包含发布会带上 .NET 运行时,通常明显大于框架依赖发布;实际体积受 .NET 版本、RID、依赖、原生库和 ReadyToRun 等选项影响,应以项目实测为准。改用
--self-contained false可减小发布产物,但目标机必须安装匹配的 .NET Desktop Runtime。单文件中的托管程序集通常直接加载;原生库是否打入并自解压取决于发布属性,PDB 默认也不包含在单文件中。
二、ReadyToRun / Trim
ReadyToRun(R2R):预编译成原生机器码,启动更快,体积大些:
| |
| |
Trim(裁剪):移除没用到的代码,减小体积。WinForms 对 Trim 支持差(大量反射 + 设计器),别开:
| |
WinForms 框架本身并不适合直接按 Native AOT 应用发布;反射、动态代码和部分组件也会带来额外限制。MAUI 和 WinUI 不是 WinForms Native AOT 的直接替代方案,不应仅为了 AOT 就迁移 UI 框架。如果原生编译是硬性需求,需按目标框架的官方兼容性说明单独评估和验证。
三、ClickOnce:老牌自动更新
ClickOnce(.NET Framework 2.0 起)是 WinForms/WPF 的"零摩擦安装 + 自动更新"方案:用户点网页链接 → 装到用户目录(不需管理员)→ 每次启动检查更新。
.NET 8 下 ClickOnce 仍支持(VS 项目属性 → Publish,或 publish 配置),流程:
| |
VS 里:项目属性 → Publish → ClickOnce 发布向导,设发布位置、更新策略(启动时检查 / 间隔 N 天)、签名。
| |
ClickOnce 会根据部署清单管理版本和文件,更新体验受包体、文件变更和网络环境影响。它仍是 WinForms 内网分发和自动更新的低成本选项。
四、MSIX:现代打包
MSIX(Windows 10+)是现代 Windows 应用包格式,提供包标识、可预测的安装/卸载和商店或企业分发能力。是否自动更新取决于 Microsoft Store 或 App Installer 等分发配置;打包的桌面程序也不能一概称为“运行在沙箱中”。
| |
打包用 Visual Studio 的"Windows 应用程序打包项目"(WAP)或 MakeAppx 工具。MSIX 要签名(证书),企业分发用内部 CA,商店分发用 MS Store 关联。
五、自动更新实现
不用 ClickOnce/MSIX 时,更新程序至少要完成下面这条受信任的链路:
| |
不要把“下载 exe、覆盖原文件、
Application.Restart()”当作可上线的更新方案。它缺少签名校验、原子替换、失败回滚、权限和文件占用处理,既容易更新失败,也可能变成供应链攻击入口。
开源方案:Velopack、Squirrel.Windows,封装了检查/下载/替换/快捷方式全套。
六、代码签名
未签名或缺少信誉的 exe 可能触发 Windows SmartScreen 警告。面向企业或公网正式分发时应进行代码签名 :
| |
| |
内部分发用自签名证书(企业 CA 推到用户机器的根证书);公网分发用商业代码签名证书。
七、部署选型
| |
八、小结
| |
下一篇:WinForms vs WPF——两个框架对照、选型决策、迁移路径,系列收官。