Skip to Content
Week 09Day 5 - 打包与发布

Day 5 - 打包与发布

建议用时:180-210 分钟

你将学会什么

  • dotnet rundotnet builddotnet publish 的区别
  • Debug 和 Release 的区别
  • 什么是发布目录
  • 什么是 RID
  • 什么是自包含发布
  • 发布后应该检查哪些内容

本页不是让你背命令。发布的核心是:把开发电脑上能跑的项目,变成一个独立的发布目录,然后在这个目录里重新验证程序能不能启动、资源在不在、数据能不能保存。

本页固定顺序

  1. 先学第一部分:弄懂今天最小、最重要的知识,并运行短例子。
  2. 再学第二部分:把刚学的知识组合成一个完整例子。
  3. 然后做第三部分:自己跟着敲,再完成重复训练和每日小测。
  4. 最后做第四部分:先独立完成作业,再用完整答案检查。

学习衔接

上一页学习的是“数据持久化”,今天继续学习“打包与发布”。先使用上一页已经会的写法,再只增加今天这个新知识点;如果前置内容还不能独立敲出,先回上一页复习,不要硬跳。

今天的最低通过线

第一次学习不要求背完整页。完成下面 3 项,就可以继续:

  • 能用自己的话说明“打包与发布”解决什么问题。
  • 把第一部分的短例子亲手敲完,并确认每个例子都能运行。
  • 不看完整答案完成第三部分至少前 3 个例子,再主动改一个值观察结果。

第一部分:先学原理和最小知识

这一部分从最小知识开始。先读解释,再把紧跟着的短例子敲一遍。发布最容易出问题,是因为很多人只在开发目录里点运行,没有真的从发布目录启动过。

runbuildpublish 的区别

命令它做什么什么时候用
dotnet run编译并直接运行项目平时开发调试
dotnet build只编译,检查代码能不能过写完代码后检查错误
dotnet publish生成发布目录准备交给别人运行

你平时看到窗口能打开,通常是 run 成功。

发布要看的不是开发目录,而是 publish 生成出来的目录。

Debug 和 Release 的区别

模式用途特点
Debug开发调试方便查问题,体积和性能不是重点
Release发布交付编译优化更多,更接近真实运行

发布时一般用:

dotnet publish -c Release

-c 是 configuration 的缩写,表示编译配置。

什么是发布目录

发布目录就是 dotnet publish 输出的一整个文件夹。

例如:

dotnet publish -c Release -o ./artifacts/publish

这里的 ./artifacts/publish 就是发布目录。

用户真正需要的是这个目录里的文件,而不是你的源码文件夹。

什么是 RID

RID 是 Runtime Identifier,表示目标运行系统。

常见 RID:

RID目标系统
osx-arm64Apple Silicon Mac
osx-x64Intel Mac
win-x6464 位 Windows
linux-x6464 位 Linux

如果你在 macOS 上发布给 Windows 用,就要指定 Windows 的 RID:

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

什么是自包含发布

自包含发布就是把 .NET 运行时一起带上。

--self-contained true

它的好处是:目标电脑不需要单独安装 .NET Runtime。

它的代价是:发布目录会更大。

对应的非自包含发布是:

--self-contained false

它的好处是:发布目录更小。

它的代价是:目标电脑需要先安装对应的 .NET Runtime。

为什么发布后要在干净目录运行

开发目录里有源码、临时文件、缓存文件,很多问题会被掩盖。

例如:

  • 图片在开发目录能找到,发布目录没有复制过去。
  • JSON 文件在开发目录能写,发布目录没有写权限。
  • 配置文件在源码旁边,发布目录没有。
  • Debug 能跑,Release 才暴露绑定或资源问题。

所以发布后要进入发布目录,再启动程序。

发布不是安装包

dotnet publish 生成的是发布目录,不一定是安装包。

在 macOS 上,它默认不会自动生成完整 .app 安装包。

在 Windows 上,它默认也不是 .msi 安装程序。

先学会发布目录,再考虑后面的安装包、签名、公证、自动更新。

打包发布常用命令速查

需求命令
还原依赖dotnet restore
Debug 构建dotnet build
Release 构建dotnet build -c Release
发布到目录dotnet publish -c Release -o ./publish
指定 macOS ARMdotnet publish -c Release -r osx-arm64
指定 Windows x64dotnet publish -c Release -r win-x64
自包含发布--self-contained true

发布检查顺序:

build -> publish -> 进入发布目录 -> 启动程序 -> 跑主流程

第二部分:把知识组合成完整例子

今天要做的是:把 Avalonia 项目发布到一个单独目录。

最小发布命令

在项目 .csproj 所在目录执行:

dotnet publish -c Release -o ./artifacts/publish

执行后会出现:

artifacts/ publish/ ProductApp ProductApp.dll ProductApp.deps.json ProductApp.runtimeconfig.json 其他依赖文件

macOS Apple Silicon 自包含发布

如果目标机器是 Apple Silicon Mac,可以执行:

dotnet publish -c Release -r osx-arm64 --self-contained true -o ./artifacts/osx-arm64

Windows x64 自包含发布

如果目标机器是 64 位 Windows,可以执行:

dotnet publish -c Release -r win-x64 --self-contained true -o ./artifacts/win-x64

发布后必须检查

发布成功不等于可以交付。发布后至少检查这几件事:

1. 发布目录存在。 2. 主程序文件存在。 3. 程序能从发布目录启动。 4. 图片、样式、资源能正常显示。 5. JSON 保存和读取能正常工作。 6. 错误提示和日志位置正常。 7. 版本号和发布说明写清楚。

第三部分:跟着执行命令

从这里开始动手。每执行一个命令,都先看输出是否成功,再继续下一步。

第 1 步:确认当前在项目目录

先进入 .csproj 所在目录。

cd /Users/yao/Desktop/csharp-avalonia-nextra

如果你的 Avalonia 项目在子目录里,就进入那个子目录。

然后确认目录里有 .csproj

ls *.csproj

如果这里没有输出,说明你当前不在项目目录。

第 2 步:先 build

先编译一次:

dotnet build

看到类似结果才继续:

0 个错误

如果 build 都失败,先修编译错误,不要直接 publish。

第 3 步:做最小发布

先做一个不指定系统的发布:

dotnet publish -c Release -o ./artifacts/publish

解释:

  • publish 表示生成发布产物。
  • -c Release 表示用 Release 模式。
  • -o ./artifacts/publish 表示输出到指定目录。

第 4 步:查看发布目录

执行:

ls ./artifacts/publish

你应该能看到应用程序文件、.dll.json、依赖文件。

如果发布目录为空,说明 publish 没成功。

第 5 步:从发布目录启动

macOS 或 Linux 可以先进入发布目录:

cd ./artifacts/publish

如果里面有可执行文件,例如 ProductApp,执行:

./ProductApp

如果只有 DLL,执行:

dotnet ProductApp.dll

Windows 上可以在发布目录里双击 .exe,也可以在命令行执行:

ProductApp.exe

第 6 步:发布 macOS Apple Silicon

如果目标是 Apple Silicon Mac:

dotnet publish -c Release -r osx-arm64 --self-contained true -o ./artifacts/osx-arm64

发布后检查:

ls ./artifacts/osx-arm64

第 7 步:发布 Windows x64

如果目标是 Windows x64:

dotnet publish -c Release -r win-x64 --self-contained true -o ./artifacts/win-x64

发布后检查:

ls ./artifacts/win-x64

第 8 步:写发布说明

在发布目录旁边放一个说明文件,例如:

RELEASE-NOTES.txt

内容可以这样写:

版本:1.0.0 发布日期:2026-06-12 包含功能: 1. 商品列表显示 2. 新增商品 3. 保存 JSON 4. 读取 JSON 运行方式: 1. 解压发布目录。 2. 进入发布目录。 3. 启动 ProductApp。 验收清单: 1. 程序能启动。 2. 能新增商品。 3. 能保存 JSON。 4. 关闭后重新打开,能读取 JSON。 5. 没有缺失资源或启动错误。

第 9 步:发布后验收

每次发布后都按这个顺序检查:

  1. 删除旧发布目录,重新 publish。
  2. 进入新发布目录。
  3. 从发布目录启动程序。
  4. 点一遍主要功能。
  5. 保存一份数据。
  6. 关闭程序再打开。
  7. 读取刚才保存的数据。
  8. 记录版本号和发布日期。

常见错误和修法

错误为什么错修法
在错误目录执行发布命令找不到项目文件先确认当前目录有 .csproj
只运行不发布dotnet run 不是交付产物使用 dotnet publish -c Release
发布后不测试输出目录开发目录能跑不代表发布目录能跑进入发布目录重新启动程序
没区分目标系统发布产物可能不能在目标机器运行指定正确 RID
发布目录混放多个版本后期无法回滚每个版本单独目录

小白重复敲写训练

发布训练要亲手检查输出目录,不只记命令。

训练 1:普通发布

dotnet publish -c Release

找到 bin/Release 下的发布目录,确认主程序和依赖文件存在。

训练 2:指定运行平台

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

改动任务:根据自己的系统尝试 osx-arm64linux-x64

训练 3:单文件发布

dotnet publish -c Release -r win-x64 --self-contained true \ -p:PublishSingleFile=true

每次发布后完成三项检查:文件在哪里、能否启动、配置文件是否齐全。

每日小测

做完本页后,用这 5 题检查是否真的掌握。

1. 判断题

本页的目标不是只把代码运行起来,还要能说清楚“为什么这样写”。

答案:对。能运行只是第一步,能解释原理、常用操作和常见错误,才说明本页内容进入了可复用能力。

2. 填空题

本页主题是:打包与发布。今天至少要掌握的 3 个点是:

1. `dotnet run`、`dotnet build`、`dotnet publish` 的区别 2. Debug 和 Release 的区别 3. 什么是发布目录

答案:以上 3 点必须能用自己的代码跑通,不能只停留在阅读。

3. 流程题

遇到本页相关功能时,先按什么顺序处理?

答案:先看完整例子,确认最终效果;再读原理和名词;然后跟着第三部分从空项目敲代码;最后对照作业答案检查。

4. 找错误题

如果本页代码运行失败,第一步应该做什么?

答案:先看终端或 IDE 里的第一条错误,找到文件名和行号;不要同时改很多地方。再回到本页的“常见错误和修法”表格,对照错误类型逐项排查。

5. 改需求题

在本页完整例子跑通后,至少改一个小需求。

可选改法:

  • 改一个字段名称。
  • 多加一个校验条件。
  • 多输出一行结果。
  • 把固定数据改成用户输入。
  • 把一次处理改成多条数据处理。

答案标准:修改后能重新运行,并能说明这次修改影响了哪一段逻辑。重点检查:dotnet run、dotnet build、dotnet publish 的区别。

上位机专项练习

发布要让目标电脑在没有开发环境时也能启动,并明确配置、日志和数据放在哪里。

下面 3 个例子都要亲手敲。先运行原代码,再完成每个例子后面的改动任务。

专项例子 1:发布 Windows x64

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

运行结果或界面效果:

生成包含 .NET 运行时的 Windows 发布目录

改动任务: 再了解 framework-dependent 发布区别。

专项例子 2:发布目录检查

publish/ Hmi.App.exe appsettings.json assets/ README.txt

运行结果或界面效果:

程序、配置、资源和说明齐全

改动任务: 增加 logs 目录说明。

专项例子 3:显示应用版本

Version? version = Assembly.GetExecutingAssembly().GetName().Version; Console.WriteLine($"HMI Version {version}");

运行结果或界面效果:

HMI Version 1.0.0.0

改动任务: 把版本写进项目文件并重新发布。

第四部分:作业完整答案

作业要求:发布一个 Avalonia 项目,生成 Release 发布目录,并写出发布说明和验收清单。

答案 1:最小发布命令

dotnet build dotnet publish -c Release -o ./artifacts/publish

答案 2:macOS Apple Silicon 发布命令

dotnet publish -c Release -r osx-arm64 --self-contained true -o ./artifacts/osx-arm64

答案 3:Windows x64 发布命令

dotnet publish -c Release -r win-x64 --self-contained true -o ./artifacts/win-x64

答案 4:发布说明

版本:1.0.0 发布日期:2026-06-12 项目名称: ProductApp 发布目标: Release 版本 包含功能: 1. 商品列表显示 2. 新增商品 3. 编辑商品 4. 删除商品 5. 搜索商品 6. 保存 JSON 7. 读取 JSON 运行方式: 1. 解压发布目录。 2. 进入发布目录。 3. 启动 ProductApp。 注意事项: 1. 如果是非自包含发布,目标电脑需要安装对应 .NET Runtime。 2. 如果是自包含发布,目录会更大,但目标电脑不需要单独安装 Runtime。 3. 第一次启动后,程序会在当前用户的应用数据目录保存 JSON 文件。

答案 5:发布验收清单

发布目录检查: 1. 发布目录存在。 2. 主程序文件存在。 3. ProductApp.dll 存在。 4. ProductApp.runtimeconfig.json 存在。 5. 资源文件没有缺失。 运行检查: 1. 程序能从发布目录启动。 2. 主窗口能显示。 3. 新增商品能成功。 4. 保存 JSON 能成功。 5. 关闭程序再启动,读取 JSON 能恢复数据。 6. 失败操作有提示,不会直接崩溃。 交付检查: 1. 版本号写清楚。 2. 发布日期写清楚。 3. 运行方式写清楚。 4. 是否需要安装 .NET Runtime 写清楚。

为什么这个答案是对的

这个答案覆盖了发布的完整链路:

阶段内容作用
编译dotnet build先确认代码能过
发布dotnet publish -c Release生成发布目录
定目标-r osx-arm64 / -r win-x64指定运行系统
定依赖--self-contained true决定是否带上 Runtime
验收发布清单确认目录真的可运行

只会执行 publish 还不够。能从发布目录启动,并且主要功能跑通,才算完成发布。