跳到正文

为 .NET 应用制作 Windows 安装程序(WPF、WinForms、控制台)

用 dotnet publish 发布 .NET 桌面应用,在依赖框架与独立部署之间做出选择,然后把发布文件夹打包成带快捷方式和卸载程序的 Setup.exe。

更新于 2026年10月31日 · 阅读约 4 分钟

Visual Studio 负责构建你的 WPF 或 WinForms 应用,dotnet publish 则生成一个可以在任何地方运行的文件夹。缺的那一环是安装程序:开始菜单项、Program Files 文件夹、Windows 设置里的卸载条目。老牌的 ClickOnce 和 Visual Studio Installer Projects 仍然存在,但两者都已显得过时。下面是从 .NET 项目到 Setup.exe 最直接的一条路。

第 1 步:发布应用

发布会生成一个包含应用所需全部内容的文件夹。在项目文件夹中运行:

dotnet publish -c Release -r win-x64 --self-contained true

输出位于 bin\Release\net8.0-windows\win-x64\publish\(路径中的目标框架随你的项目而变)。你要分发的就是这个文件夹。

唯一需要认真决定的事:

  • 独立部署(--self-contained true)会打包 .NET 运行时。文件夹有 70 到 150 MB,但在任何 Windows 机器上都能直接运行,无需事先安装任何东西。面向公众分发的软件请选择这一项。
  • 依赖框架(--self-contained false)只有几 MB,但用户必须已安装匹配的 .NET Desktop Runtime,否则应用在首次启动时会弹出下载提示。适合托管机器上的内部工具。

一些有用的选项:

  • -p:PublishReadyToRun=true 对应用进行预编译,启动更快。
  • -p:PublishSingleFile=true 把输出合并为一个 .exe。它可以用,但有了安装程序就没有理由再用它,而且单文件应用会在首次运行时解包原生库。普通文件夹更简单。
  • 裁剪(PublishTrimmed)不支持 WPF 和 WinForms,请保持关闭。

在项目文件中设置应用图标,让发布出来的 .exe 带上它:

<PropertyGroup>
  <ApplicationIcon>app.ico</ApplicationIcon>
</PropertyGroup>

从发布文件夹里运行一次发布出来的 .exe,最好在一台没装 Visual Studio 的机器上,确认没有缺少任何东西。

第 2 步:压缩发布文件夹

把 publish` 的*内容*压缩成 zip:.exe、各个 DLL、.deps.json、.runtimeconfig.json 以及所有内容文件。不要包含 .pdb` 文件,除非你希望在客户机器上保留崩溃符号。

第 3 步:构建安装程序

  1. 把 zip 上传到 ExeTup。它会把你的应用 .exe 选为主程序;请确认一下,因为独立部署的发布中包含 createdump.exe,而它并不是主程序。
  2. 填写名称、版本(与项目中的 <Version> 保持一致)、发布者和许可协议。
  3. 经典的 Program Files 桌面应用选择所有用户;客户可能没有管理员权限时选择当前用户。
  4. win-x64 发布保持 64 位;win-x86 则选择 32 位。
  5. 上传同一个 app.ico,启用快捷方式,然后构建。

下载 Setup.exe,在 Windows 上测试安装和卸载。

.NET 专属说明

  • 更新。发布一个版本号更高的新安装程序。覆盖旧版本安装会替换文件;安装程序不包含自动更新通道。
  • 设置和数据。把用户数据写入 %APPDATA% 或 %LOCALAPPDATA%,不要写在 .exe 旁边。Program Files 对普通用户是只读的,而且卸载程序只会删除它安装的内容。
  • 先决条件。独立部署的发布不需要任何其他东西。如果你的应用需要 Visual C++ 运行时或数据库驱动,请在文档中说明;安装程序不会链式调用其他安装程序。
  • 代码签名。压缩前先给发布出来的 .exe 签名,然后再给下载下来的 Setup.exe 签名。参见 SmartScreen 指南。

替代方案

  • Visual Studio Installer Projects 在 Visual Studio 内部生成 MSI 文件。目前仍以扩展形式提供,功能有限,处理独立部署的发布时很别扭。
  • ClickOnce 提供带自动更新的按用户安装,绑定在一台由你维护的 Web 服务器上。
  • WiX Toolset 从 XML 构建 MSI 文件,是企业级 MSI 打包的标准。功能强大,学习曲线也同样陡峭。
  • MSIX 是 Microsoft 较新的包格式,面向 Microsoft Store 时最合适。

格式何时重要,请参见 MSI 与 EXE 安装程序对比。

常见问题

我应该选择依赖框架还是独立部署?

任何面向公众提供的东西都选独立部署,这样应用无需下载运行时即可运行。IT 部门统一管理 .NET 运行时的机器上的内部工具,可选依赖框架。

安装程序包含 .NET 运行时吗?

如果你以独立部署方式发布,那么包含,因为它是发布文件夹的一部分。安装程序会原样打包 zip 里的所有内容。

我能为组策略生成 MSI 吗?

ExeTup 构建的是 Setup.exe。它可以用 /S 静默安装,这已经覆盖了大多数脚本化部署。对于只接受 MSI 的策略,WiX 才是合适的工具。

这适用于哪些 .NET 版本?

任何能生成发布文件夹的版本:.NET 6、7、8、9 及更高版本,以及用 Visual Studio 构建的 .NET Framework 应用(使用 bin\Release 输出)。

相关指南