用 dotnet 命令发布程序
2024-11-04 23:14:26

很久以前,发布程序都是将配置改为 Release 编译一下,得到二进制文件打包给客户,这个习惯一直延续至今。
好像是从 .NET Core 时代开始,微软为了跨平台搞了个推出了一个发布的概念,也就是在编译后多了一个打包的过程。

dotnet 命令行发布

废话不多说,先看一条发布命令:

1
dotnet publish MyProject -c Release -f net8.0-windows -r win-x64 --sc false -o ./publish -p:Platform=x64 -p:PublishSingleFile=true
参数 对应MSBuild属性 说明
-c Configuration 解决方案配置,一般就是DebugRelease。
-f TargetFramework TargetFrameworks中的值之一。
-r RuntimeIdentifier 影响 nuget 包将哪些附件复制到输出目录。
–sc SelfContained true表示将依赖的.NET框架文件一并复制到发布目录,文件夹会非常大。但是不用再安装运行库。
-o PublishDir 发布目录位置。
-p:Platform Platform 解决方案平台,一般就是AnyCPUx86x64ARM32AMR64
-p:PublishSingleFile PublishSingleFile 是否将托管 DLL 文件合并为一个 exe 文件,这样发布目录会很干净,不会有大量 DLL 文件。


可以输入dotnet publish /?查看详细的说明。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Description:
适用于 .NET 平台的发布服务器

用法:
dotnet publish [<PROJECT | SOLUTION>...] [options]

参数:
<PROJECT | SOLUTION> 要操作的项目或解决方案文件。如果没有指定文件,则命令将在当前目录里搜索一个文件。

选项:
--ucr, --use-current-runtime 将当前运行时用作目标运行时。
-o, --output <OUTPUT_DIR> 要放置已发布项目的输出目录。
--artifacts-path <ARTIFACTS_DIR> 工件路径。项目中的所有输出(包括生成、发布和打包输出)都将放到指定路径下的子文件夹中。
--manifest <MANIFEST> 指向目标清单文件的路径,该文件包含要通过发布步骤执行的包的列表。
--no-build 发布之前不要生成项目。Implies --no-restore.
--sc, --self-contained 随应用程序一起发布 .NET 运行时,这样就不需要在目标计算机上安装运行时。
默认值为 "false"。但目标为 .NET 7 或更低版本时,如果指定了运行时标识符,则默认值为 "true"。
--no-self-contained 将应用程序发布为依赖框架的应用程序。目标计算机上必须安装兼容的 .NET 运行时才能运行该应用程序。
--nologo 不显示启动版权标志或版权消息。
-f, --framework <FRAMEWORK> 要发布的目标框架。必须在项目文件中指定目标框架。
-r, --runtime <RUNTIME_IDENTIFIER> 要发布的目标运行时。在创建自包含部署时使用。
默认情况下发布依赖于框架的应用程序。
-c, --configuration <CONFIGURATION> 发布所对应的配置。对于 NET 8.0 及更高版本的项目,默认值为 "Release",但对于较低版本的项目,默认值为 "Debug"。
--version-suffix <VERSION_SUFFIX> 设置生成项目时使用的 $(VersionSuffix) 属性的值。
--interactive 允许命令停止和等待用户输入或操作(例如,用以完成身份验证)。
--no-restore 生成前请勿还原项目。
-v, --verbosity <LEVEL> 设置 MSBuild 详细程度。允许值为 q[uiet]、m[inimal]、n[ormal]、d[etailed] 和 diag[nostic]。
-a, --arch <ARCH> 目标体系结构。
--os <OS> 目标操作系统。
--disable-build-servers 强制命令忽略任何永久性生成服务器。
-?, -h, --help 显示命令行帮助。

.pubxml 文件发布

在 Visual Studio 中右键选择项目,点击发布也可以用向导方式发布程序

然后项目文件夹Properties\PublishProfiles下会生成相应的.pubxml文件。

1
2
3
4
5
6
7
8
9
10
11
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<TargetFramework>net8.0-windows</TargetFramework>
<Platform>x64</Platform>
<PublishDir>./publish</PublishDir>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<SelfContained>false</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
</Project>

还可以用命令行来引用.pubxml文件来发布

1
dotnet publish MyProject -p:PublishProfile=FolderProfile

但是我个人不推荐这么做,因为dotnet不会去读取某些属性值,MSDN 上说的:

.pubxml 文件中的某些属性仅受 Visual Studio 使用,对 dotnet publish 没有影响。 我们正在努力使 CLI 与 Visual Studio 的行为更加一致。 但 CLI 永远不会使用某些属性。 CLI 和 Visual Studio 都执行发布的打包方面,dotnet/sdk#29817 计划添加对更多与此相关的属性的支持。 但 CLI 不执行发布时部署自动化方面的操作,与此相关的属性不受支持。 不支持的最值得注意的 .pubxmldotnet publish 属性是影响生成的以下属性:

  • LastUsedBuildConfiguration
  • Configuration
  • Platform
  • LastUsedPlatform
  • TargetFramework
  • TargetFrameworks
  • RuntimeIdentifier
  • RuntimeIdentifiers


所以我还是喜欢用命令行的方式发布。

总结

简单地说,发布的最终目的就是为了以下三个功能:

  1. SelfContained。决定是否将 .NET 运行库文件一并打包,这样客户机可以避免安装 .NET 运行时。
  2. PublishSingleFile。决定是否将所以依赖的程序集文件合并到一个可执行文件中。
  3. PublishAot。是否启用 AOT 编译,生成的文件是非托管文件,不依赖 .NET 运行时,和 C/C++ 一样,一般用于 DLL 项目。

相关阅读

dotnet publish 命令
发布配置文件
单文件部署