本文介绍了发布 .NET 应用程序的不同方法。 它涵盖发布模式、如何生成可执行文件和跨平台二进制文件,以及每个方法对部署和运行时环境的影响。 可以使用 .NET CLI 或 Visual Studio 发布 .NET 应用程序。
有关发布的简短教程,请参阅 教程:使用 Visual Studio Code 发布 .NET 控制台应用程序。
有关发布的简短教程,请参阅 教程:使用 Visual Studio 发布 .NET 控制台应用程序。
什么是发布
发布 .NET 应用意味着编译源代码以创建可执行文件或二进制文件及其依赖项和相关文件以供分发。 发布后,可将应用部署到服务器、分发平台、容器或云环境。 发布过程为部署和使用在开发环境之外准备应用。
发布模式
发布应用有两种主要方法。 影响此决策的一些因素包括部署环境是否安装了适当的 .NET 运行时,以及是否需要将运行时与应用捆绑的特定编译功能。 这两种发布模式包括:
发布自包含
此模式生成一个发布文件夹,其中包含用于启动应用的特定于平台的可执行文件、包含应用代码的已编译二进制文件、任何应用依赖项以及运行应用所需的 .NET 运行时。 运行应用的环境不需要预安装 .NET 运行时。发布依赖于框架的
此模式生成一个发布文件夹,其中包含用于启动应用的特定于平台的可执行文件、包含应用代码的已编译二进制文件以及任何应用依赖项。 运行应用的环境必须安装应用可以使用的 .NET 运行时版本。 可以生成特定于平台的可选可执行文件。
重要
使用运行时标识符(RID)指定目标平台。 有关 RID 的详细信息,请参阅 .NET RID 目录。
发布基础知识
发布 <TargetFramework> 应用时,项目文件的设置指定默认目标框架。 可以将目标框架更改为任何有效的目标框架名字对象(TFM)。 例如,如果项目使用 <TargetFramework>net9.0</TargetFramework>,则会创建面向 .NET 9 的二进制文件。
如果要以多个框架为目标,可以将设置设置为 <TargetFrameworks> 多个 TFM 值,用分号分隔。 生成应用时,将针对项目定义的每个目标框架生成应用。 但是,发布应用时,必须指定目标框架:
默认生成配置模式为 Release,除非使用 -c 参数进行更改。
dotnet publish -c Release -f net9.0
命令的默认输出目录 dotnet publish 为 ./bin/<BUILD-CONFIGURATION>/<TFM>/publish/。 例如, dotnet publish -c Release -f net9.0 发布到 ./bin/Release/net9.0/publish/. 但是,可以选择为所有生成输出选择简化的输出路径和文件夹结构。 有关详细信息,请参阅 Artifacts 输出布局。
在 Visual Studio 中,为每个目标框架创建单独的发布配置文件。
可移植二进制文件
发布 .NET 应用时,可以面向特定平台或创建可移植二进制文件。 默认情况下,即使创建可移植二进制文件,.NET 也会在可移植 DLL 旁边发布特定于平台的可执行文件,除非显式禁用此行为。
由于属性默认为 ,因此创建了 UseAppHost 特定于平台的 true可执行文件。 若要仅发布没有特定于平台的可执行文件的可移植 DLL,请设置为UseAppHostfalse命令行 (-p:UseAppHost=false) 或作为项目属性。
面向特定平台的好处是,它可以处理应用可能需要的 本机依赖项 ,确保与目标平台的特定要求兼容。
本机依赖项
如果应用具有本机依赖项,则发布为可移植二进制文件时,它可能不会在不同的作系统上运行。 例如,依赖于 Windows API 的应用不会在 macOS 或 Linux 上本机运行。 你需要提供特定于平台的代码并为每个平台编译可执行文件。
此外,如果引用的库提供特定于平台的依赖项,则应用可能不会在每个平台上运行。 但是,当你发布和面向特定平台时,NuGet 包的特定于平台的依赖项将复制到发布文件夹。
若要确保应用使用其本机依赖项发布,请针对特定平台发布:
dotnet publish -c Release -r <RID>
-c Release此开关将生成配置设置为 Release,该版本已针对生产部署进行优化。
-r <RID>此开关使用运行时标识符(RID)来指定目标平台,并确保包含本机依赖项(如果需要)。 有关运行时标识符的列表,请参阅 运行时标识符(RID)目录。
- 右键单击 解决方案资源管理器 中的项目,然后选择“ 发布”。
- 如果这是首次发布,请选择 “文件夹 ”作为发布目标,然后选择“ 下一步”。
- 选择文件夹位置或接受默认值,然后选择“ 完成”。
- 在发布配置文件中,选择“ 显示所有设置”。
- 将 目标运行时 设置为所需的平台(例如 ,适用于 64 位 Windows 的 win-x64 )。
- 选择“ 保存 ”,然后选择 “发布”。
有关运行时标识符的列表,请参阅 运行时标识符(RID)目录。
快速参考
下表提供了有关如何发布应用的快速示例。
| 发布模式 | 命令 |
|---|---|
| 依赖于框架的部署 | dotnet publish -c Release [-r <RID>] |
| 依赖于框架的部署 (DLL) | dotnet publish -c Release -p:UseAppHost=false |
| 独立部署 | dotnet publish -c Release [-r <RID>] --self-contained true |
| 单文件部署 | dotnet publish -c Release [-r <RID>] -p:PublishSingleFile=true |
| 本机 AOT 部署 | dotnet publish -c Release [-r <RID>] -p:PublishAot=true |
| ReadyToRun 部署 | dotnet publish -c Release [-r <RID>] -p:PublishReadyToRun=true |
| 容器部署 | dotnet publish -c Release [-r <RID>] -t:PublishContainer |
依赖于框架的部署
从 CLI 或 Visual Studio 发布时,依赖于框架的部署是默认模式。 在此模式下,将创建特定于平台的可执行主机来托管跨平台应用。 主机可执行文件文件名因平台而异,并命名为 <PROJECT-FILE>.exe类似于 . 可以直接运行此可执行文件,而不是调用 dotnet <PROJECT-FILE>.dll,这仍然是运行应用的可接受方法。
你的应用配置为面向特定版本的 .NET。 目标 .NET 运行时需要位于应用运行的环境中。 例如,如果应用面向 .NET 9,则应用运行的任何环境都必须安装 .NET 9 运行时。
发布依赖于框架的部署会创建一个应用,该应用会自动前滚到运行应用的环境中可用的最新 .NET 安全修补程序。 有关编译时的版本绑定的详细信息,请参阅 选择要使用的 .NET 版本。
优势
- 小型部署:仅分发应用及其依赖项。 运行应用的环境必须已安装 .NET 运行时。
- 跨平台:应用和任何 。基于 NET 的库在其他作系统上运行。
- 使用最新的修补运行时:应用使用环境中安装的最新运行时。
弊
- 需要预安装运行时:仅当应用所面向的 .NET 版本已安装在环境中时,应用才能运行。
- .NET 可能会更改:运行应用的环境可能会使用较新的 .NET 运行时,这可能会更改应用行为。
发布
dotnet publish -c Release [-r <RID>]
-c Release此开关将生成配置设置为 Release,该版本已针对生产部署进行优化。
-r <RID>此开关使用运行时标识符(RID)来指定目标平台,并确保包含本机依赖项(如果需要)。 有关运行时标识符的列表,请参阅 运行时标识符(RID)目录。
或者显式:
dotnet publish -c Release [-r <RID>] --self-contained false
--self-contained false此开关显式告知 .NET SDK 创建依赖于框架的部署。
- 右键单击 解决方案资源管理器 中的项目,然后选择“ 发布”。
- 如果这是首次发布,请选择 “文件夹 ”作为发布目标,然后选择“ 下一步”。
- 选择文件夹位置或接受默认值,然后选择“ 完成”。
- 在发布配置文件中,选择“ 显示所有设置”。
- 将 部署模式 设置为 依赖框架 (这是默认值)。
- 将 目标运行时 设置为所需的平台(例如 ,适用于 64 位 Windows 的 win-x64 )。
- 选择“ 保存 ”,然后选择 “发布”。
配置 .NET 安装搜索行为
在 .NET 9 及更高版本中,可以通过属性配置已发布可执行文件AppHostDotNetSearchAppHostRelativeDotNet的 .NET 安装搜索路径。
AppHostDotNetSearch 允许指定可执行文件查找 .NET 安装的一个或多个位置:
-
AppLocal:应用可执行文件的文件夹 -
AppRelative:相对于应用可执行文件的路径 -
EnvironmentVariable:环境变量的值DOTNET_ROOT[_<arch>] -
Global: 已注册 和 默认 的全局安装位置
AppHostRelativeDotNet指定相对于包含时AppHostDotNetSearchAppRelative要搜索的可执行文件的路径。
有关详细信息,请参阅 AppHostDotNetSearchAppHostRelativeDotNetapphost 中的位置和安装位置选项。
跨平台 DLL 部署
或者,可以将应用发布为跨平台 DLL,而无需特定于平台的可执行文件。 在此模式下,会在发布输出文件夹中创建一个 <PROJECT-NAME>.dll 文件。 若要运行应用,请导航到输出文件夹并使用 dotnet <PROJECT-NAME>.dll 命令。
以跨平台 DLL 的形式发布:
dotnet publish -c Release -p:UseAppHost=false
-c Release此开关将生成配置设置为 Release,该版本已针对生产部署进行优化。
-p:UseAppHost=false此属性禁用创建特定于平台的可执行文件,只生成可移植 DLL。
- 右键单击 解决方案资源管理器 中的项目,然后选择“ 发布”。
- 如果这是首次发布,请选择 “文件夹 ”作为发布目标,然后选择“ 下一步”。
- 选择文件夹位置或接受默认值,然后选择“ 完成”。
- 在发布配置文件中,选择“ 显示所有设置”。
- 将 部署模式 设置为 依赖框架。
- 取消选中 “生成单个文件”。
- 将 目标运行时 设置为 可移植 (或留空)。
- 选择“ 保存 ”,然后选择 “发布”。
独立部署
发布独立部署(SCD)时,发布过程将创建特定于平台的可执行文件。 发布 SCD 包括运行应用所需的所有 .NET 文件,但不包括 .NET 的本机依赖项。 在应用运行之前,这些依赖项必须存在于环境中。
发布 SCD 会创建不会前滚到最新可用 .NET 安全修补程序的应用。 有关编译时的版本绑定的详细信息,请参阅 选择要使用的 .NET 版本。
优势
- 控制 .NET 版本:控制随应用部署的 .NET 版本。
- 特定于平台的目标:由于应用必须针对每个平台发布,因此很明显应用在何处运行。
弊
- 较大的部署:由于应用包含 .NET 运行时和所有依赖项,因此所需的下载大小和硬盘空间大于 依赖于框架的部署。
- 更难更新 .NET 版本:只能通过发布新版本的应用来升级 .NET 运行时。
提示
可以通过 发布剪裁 或启用 全球化固定模式来减少兼容自包含应用的总大小。 有关全球化固定模式的详细信息,请参阅 .NET 全球化固定模式。
发布
dotnet publish -c Release -r <RID> --self-contained true
-c Release此开关将生成配置设置为 Release,该版本已针对生产部署进行优化。
-r <RID>此开关使用运行时标识符(RID)来指定目标平台,并确保包含本机依赖项(如果需要)。 有关运行时标识符的列表,请参阅 运行时标识符(RID)目录。
--self-contained true此开关告知 .NET SDK 将可执行文件创建为独立部署(SCD)。
- 右键单击 解决方案资源管理器 中的项目,然后选择“ 发布”。
- 如果这是首次发布,请选择 “文件夹 ”作为发布目标,然后选择“ 下一步”。
- 选择文件夹位置或接受默认值,然后选择“ 完成”。
- 在发布配置文件中,选择“ 显示所有设置”。
- 将 部署模式 设置为 自包含模式。
- 将 目标运行时 设置为所需的平台(例如 ,适用于 64 位 Windows 的 win-x64 )。
- 选择“ 保存 ”,然后选择 “发布”。
单文件部署
将应用发布为单文件部署时,所有依赖应用程序的文件都捆绑成单个二进制文件。 此部署模型适用于依赖于框架的应用程序和独立应用程序,提供一个有吸引力的选项,用于将应用程序部署和分发为单个文件。
单文件应用始终特定于 OS 和体系结构。 需要为每个配置发布,例如 Linux x64、Linux Arm64、Windows x64 等。
优势
- 简化的分发:将应用程序部署和分发为单个可执行文件。
- 减少了文件混乱:所有依赖项都捆绑在一起,无需管理多个文件。
- 轻松部署:复制单个文件以部署应用程序。
弊
- 较大的文件大小:单个文件包含所有依赖项,使其大于单个文件。
- 启动速度较慢:必须在运行时提取文件,这可能会影响启动性能。
- 特定于平台:必须为每个目标平台发布单独的文件。
单文件部署可以与其他优化(例如 剪裁 和 ReadyToRun 编译 )结合使用,以便进一步优化。
有关单文件部署的详细信息,请参阅 单文件部署。
发布
dotnet publish -c Release -r <RID> -p:PublishSingleFile=true
-c Release此开关将生成配置设置为 Release,该版本已针对生产部署进行优化。
-r <RID>此开关使用运行时标识符(RID)来指定目标平台,并确保包含本机依赖项(如果需要)。 有关运行时标识符的列表,请参阅 运行时标识符(RID)目录。
-p:PublishSingleFile=true此属性将所有依赖应用程序的文件捆绑到一个二进制文件中。
- 右键单击 解决方案资源管理器 中的项目,然后选择“ 发布”。
- 如果这是首次发布,请选择 “文件夹 ”作为发布目标,然后选择“ 下一步”。
- 选择文件夹位置或接受默认值,然后选择“ 完成”。
- 在发布配置文件中,选择“ 显示所有设置”。
- 将 部署模式 设置为 自包含 模式或 依赖于框架。
- 将 目标运行时 设置为所需的平台(例如 ,适用于 64 位 Windows 的 win-x64 )。
- 检查 “生成单个文件”。
- 选择“ 保存 ”,然后选择 “发布”。
本机 AOT 部署
本机 AOT 部署将应用直接编译为本机代码,无需运行时。 此发布选项使用 自包含部署 模式,因为编译的本机代码必须包含运行应用程序所需的所有内容。 这会导致更快的启动时间和减少内存使用率,但对受支持的功能存在一些限制。
优势
- 快速启动:运行时不需要 JIT 编译,导致应用程序启动速度更快。
- 减少内存使用量:与传统 .NET 应用程序相比,内存占用量较低。
- 无运行时依赖项:应用程序无需安装 .NET 运行时即可运行。
- 较小的部署大小:通常小于具有完整运行时的 自包含部署 。
弊
- 有限的框架支持:并非所有 .NET 功能和库都与本机 AOT 兼容。
- 生成时间更长:编译到本机代码所需的时间比常规生成长。
- 特定于平台:必须为每个目标平台和体系结构单独编译。
- 调试限制:与常规 .NET 应用程序相比,更复杂的调试体验。
有关本机 AOT 部署的详细信息,请参阅 本机 AOT 部署。
发布
dotnet publish -c Release -r <RID> -p:PublishAot=true
-c Release此开关将生成配置设置为 Release,该版本已针对生产部署进行优化。
-r <RID>此开关使用运行时标识符(RID)来指定目标平台,并确保包含本机依赖项(如果需要)。 有关运行时标识符的列表,请参阅 运行时标识符(RID)目录。
-p:PublishAot=true此属性启用本机 AOT 编译,该编译会将应用直接编译为本机代码。
必须在项目文件中配置本机 AOT 发布。 无法通过 Visual Studio 发布 UI 启用它。
在 解决方案资源管理器中,右键单击项目并选择 “编辑项目文件”。
将以下属性添加到 :
<PropertyGroup><PublishAot>true</PublishAot>保存项目文件。
右键单击 解决方案资源管理器 中的项目,然后选择“ 发布”。
如果这是首次发布,请选择 “文件夹 ”作为发布目标,然后选择“ 下一步”。
选择文件夹位置或接受默认值,然后选择“ 完成”。
在发布配置文件中,选择“ 显示所有设置”。
将 部署模式 设置为 自包含模式。
将 目标运行时 设置为所需的平台(例如 ,适用于 64 位 Windows 的 win-x64 )。
选择“ 保存 ”,然后选择 “发布”。
有关本机 AOT 部署的详细信息,请参阅 本机 AOT 部署。
ReadyToRun 部署
使用 ReadyToRun 编译发布应用时,应用程序程序集将编译为 ReadyToRun (R2R) 格式。 R2R 是一种提前(AOT)编译形式,它通过减少实时(JIT)编译器在加载应用程序时所需的工作量来提高启动性能。 此发布选项可用于 依赖于框架 的部署模式和 独立 部署模式。
ReadyToRun 二进制文件包含中间语言(IL)代码和相同代码的本机版本。 虽然 R2R 二进制文件大于常规程序集,但它们提供更好的启动性能。
优势
- 改进了启动时间:应用在启动期间花费更少的时间运行 JIT 编译器。
- 更好的首次使用性能:减少首次执行代码路径的延迟。
- 与现有代码兼容:适用于大多数 .NET 库和框架,无需修改。
- 灵活的部署:可以与 依赖于框架的部署 模式和 独立部署 模式结合使用。
弊
- 较大大小:应用在磁盘上较大,因为包括 IL 和本机代码。
- 生成时间越长:编译所需的时间比标准发布要长。
- 特定于平台的优化:最佳性能提升需要面向特定平台。
发布
dotnet publish -c Release -r <RID> -p:PublishReadyToRun=true
-c Release此开关将生成配置设置为 Release,该版本已针对生产部署进行优化。
-r <RID>此开关使用运行时标识符(RID)来指定目标平台,并确保包含本机依赖项(如果需要)。 有关运行时标识符的列表,请参阅 运行时标识符(RID)目录。
-p:PublishReadyToRun=true此属性启用 ReadyToRun 编译,该编译通过预编译程序集来提高启动性能。
- 右键单击 解决方案资源管理器 中的项目,然后选择“ 发布”。
- 如果这是首次发布,请选择 “文件夹 ”作为发布目标,然后选择“ 下一步”。
- 选择文件夹位置或接受默认值,然后选择“ 完成”。
- 在发布配置文件中,选择“ 显示所有设置”。
- 将 部署模式 设置为 自包含 模式或 依赖于框架。
- 将 目标运行时 设置为所需的平台(例如 ,适用于 64 位 Windows 的 win-x64 )。
- 检查 “启用 ReadyToRun 编译”。
- 选择“ 保存 ”,然后选择 “发布”。
有关 ReadyToRun 部署的详细信息,请参阅 ReadyToRun 编译。
容器部署
将应用发布为容器时,.NET SDK 会将应用程序及其依赖项打包到容器映像中,而无需单独的 Dockerfile。 此部署模式创建可在任何容器运行时(如 Docker 或 Podman)上运行的完整容器映像。 容器部署简化了容器化过程,无需编写和维护 Dockerfiles,同时提供优化的基映像。
从 .NET SDK 8.0.200 开始,容器支持默认包含,不需要额外的 NuGet 包。 对于控制台应用程序,可能需要通过将属性设置为 EnableSdkContainerSupporttrue 来显式启用容器支持。
提示
有关与容器相关的项目设置的详细信息,请参阅 容器化 .NET 应用参考。
优势
- 简化的容器化:无需为基本方案编写或维护 Dockerfiles。
- 优化的基础映像:使用具有最新安全更新的Microsoft提供的优化基础映像。
- 一致的环境:确保跨开发、测试和生产一致的运行时环境。
- 轻松分发:可在不同环境中轻松共享和部署容器映像。
- 平台隔离:应用程序在隔离容器中运行,从而减少应用程序之间的冲突。
弊
- 容器运行时依赖项:目标环境必须安装容器运行时。
- 映像大小:容器映像通常大于其他部署方法。
- 学习曲线:需要了解容器概念和工具。
- 有限的自定义:与复杂方案的自定义 Dockerfiles 相比,灵活性较低。
发布
dotnet publish -c Release [-r <RID>] /t:PublishContainer
-c Release此开关将生成配置设置为 Release,该版本已针对生产部署进行优化。
-r <RID>此开关使用运行时标识符(RID)来指定目标平台,并确保包含本机依赖项(如果需要)。 有关运行时标识符的列表,请参阅 运行时标识符(RID)目录。
-t:PublishContainer此目标将应用程序发布为容器映像。
还可以使用发布配置文件方法:
dotnet publish -c Release [-r <RID>] -p:PublishProfile=DefaultContainer
-p:PublishProfile=DefaultContainer此配置文件触发容器发布过程。
- 右键单击 解决方案资源管理器 中的项目,然后选择“ 发布”。
- 选择 容器注册表 作为发布目标,然后选择“ 下一步”。
- 选择目标容器注册表(例如 Azure 容器注册表、 Docker 中心或 通用注册表),然后选择“ 下一步”。
- 配置注册表连接详细信息和身份验证。
- 在发布配置文件中,选择“ 显示所有设置”。
- 根据需求将 部署模式 设置为 自包含 模式或依赖于 框架 。
- 将 目标运行时 设置为所需的平台(例如 Linux 容器的 linux-x64 )。
- 配置特定于容器的设置,例如映像名称和标记。
- 选择“ 保存 ”,然后选择 “发布”。
有关容器部署的详细信息,请参阅 .NET SDK 容器创建概述。