当前位置:首页 > 技术 > 正文内容

.NET 5/.NET Core应用程序发布部署完全指南

访客 技术 2026年7月30日 4

在.NET Framework时代,.NET应用程序主要部署在Windows服务器环境,当然也可以借助Mono框架运行于Linux系统。无论是部署可执行程序、IIS站点还是Windows Service,编译后的产物直接复制并简单配置即可完成部署。

进入.NET Core时代后,.NET应用程序实现了真正的跨平台支持。.NET 5发布后,沿用了.NET Core的应用程序发布模式。

由于支持跨平台部署运行,.NET 5/.NET Core应用程序面临着多平台、多场景的部署需求,包括:部署目标涵盖Windows、Linux、macOS等操作系统;目标主机是否需要安装.NET Runtime运行时;运行时版本的选择等问题。

本文将详细探讨.NET 5/.NET Core应用程序的发布部署方式。

一、两种应用程序发布模式

1. 自包含发布模式

自包含发布方式将.NET运行时与应用程序及其所有依赖项打包在一起。应用程序可以在未安装.NET运行时的操作系统上独立运行。

简而言之:把.NET Runtime运行时打包到程序运行目录中,部署目标主机无需预先安装.NET Runtime运行时。

2. 框架依赖发布模式

框架依赖发布方式仅生成应用程序本身及其依赖项。应用程序的运行需要目标主机单独安装.NET运行时。

简而言之:不包含.NET Runtime运行时,仅包含应用程序及其依赖项。部署目标主机需要单独安装相应版本的.NET Runtime运行时。

二、NET 5/.NET Core应用程序的发布命令:dotnet publish

dotnet publish命令用于将应用程序及其依赖项发布到指定文件夹,便于后续部署到目标托管系统。

dotnet publish命令的详细用法可参考官方文档:https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-publish

dotnet publish [<PROJECT>|<SOLUTION>] [-c|--configuration <CONFIGURATION>]
    [-f|--framework <FRAMEWORK>] [--force] [--interactive]
    [--manifest <PATH_TO_MANIFEST_FILE>] [--no-build] [--no-dependencies]
    [--no-restore] [--nologo] [-o|--output <OUTPUT_DIRECTORY>]
    [-p:PublishReadyToRun=true] [-p:PublishSingleFile=true] [-p:PublishTrimmed=true]
    [-r|--runtime <RUNTIME_IDENTIFIER>] [--self-contained [true|false]]
    [--no-self-contained] [-v|--verbosity <LEVEL>]
    [--version-suffix <VERSION_SUFFIX>]

dotnet publish -h|--help

dotnet publish会执行以下操作:编译应用程序,读取项目文件中指定的依赖项,然后将结果文件集发布到指定目录。输出包括:

  • 扩展名为dll的程序集中的中间语言(IL)代码
  • 一个deps.json文件,包含项目的所有依赖项信息
  • 一个runtimeconfig.json文件,指定应用程序期望的共享运行时及相关配置选项(如垃圾回收类型)
  • 应用程序依赖的NuGet包,从缓存目录复制到输出文件夹

通过dotnet publish命令,我们可以编译应用程序并生成适用于指定运行环境的部署包。

接下来创建一个.NET 5的控制台应用程序,并引用Newtonsoft.Json NuGet包。

Main函数代码如下:

using System;

namespace DemoApp
{
    class EntryPoint
    {
        static void Main(string[] args)
        {
            var message = Newtonsoft.Json.JsonConvert.SerializeObject("Hello .NET 5!");
            Console.WriteLine(message);
            Console.ReadKey();
        }
    }
}

首先执行dotnet build命令编译项目,这一步至关重要。随后使用命令行执行dotnet publish指令:

查看生成目录下的文件:

如前所述,输出包含以下内容:

  • 扩展名为dll的程序集中的中间语言代码:DemoApp.dll
  • 包含项目所有依赖项的deps.json文件:DemoApp.deps.json
  • 指定共享运行时及配置的runtimeconfig.json文件:DemoApp.runtimeconfig.json
  • 应用程序依赖的NuGet包:Newtonsoft.Json.dll

同时还生成了Windows平台的可执行文件DemoApp.exe,双击可直接运行:

![](](https://img2020.cnblogs.com/blog/23525/202102/23525-20210215101502295-1647363979.jpg)

此外,使用dotnet DemoApp.dll命令也可以直接执行:

这里产生两个疑问:

DLL文件是否可以跨平台运行?

在Linux、macOS平台下是否有对应的可执行文件?

带着这两个问题,继续往下研究。

三、生成的可执行文件和跨平台二进制文件

无论采用自包含方式还是框架依赖方式发布,默认情况下都会生成平台特定的可执行文件和跨平台二进制文件。

1. 可执行文件

可执行文件不具备跨平台特性。它们与特定的操作系统和CPU架构绑定。由于Windows和Linux下可执行文件的结构和内容不同,可执行文件按操作系统区分。

创建可执行文件时,可以选择发布为自包含或框架依赖模式。

自包含发布包含应用程序的.NET运行时,用户在运行前无需安装.NET,可直接执行。

框架依赖发布不包含.NET运行时和库,仅包含应用程序和第三方依赖项,需要目标主机安装.NET运行时。

以下演示两个平台的可执行文件生成:

① Windows x64平台

② Linux x64平台

使用命令 dotnet publish -r linux-x64 --self-contained false

生成的可执行文件:

2. 跨平台二进制文件

以框架依赖的DLL形式发布应用程序时,会创建跨平台二进制文件。DLL文件以项目命名,例如项目名为DemoApp,则生成DemoApp.dll。

以此方式发布的应用程序可通过dotnet <filename.dll>命令运行,可在任何平台上执行。

四、自包含发布选项详解

自包含发布会生成平台特定的可执行文件。

输出发布文件夹包含应用程序的所有组件,包括.NET库和目标运行时。应用程序与其他.NET应用隔离,不使用本地安装的.NET运行时。因此无需下载安装.NET运行时。

可执行二进制文件针对指定的目标平台生成。例如,应用程序名为DemoApp,发布Windows自包含可执行文件时会创建DemoApp.exe;发布Linux或macOS版本则创建名为DemoApp的可执行文件。目标平台和架构通过-r <RID>参数指定。

若应用程序包含平台特定的依赖项(如某些NuGet包),这些依赖项会随应用程序一起复制到发布文件夹。

此模式的优势:

  1. **可控.NET版本:**可自主控制随应用程序部署的.NET版本。
  2. **指定运行平台:**由于需为每个平台单独发布应用程序,可确定应用程序的运行环境。若.NET支持新平台,需先发布针对该平台的版本才能运行。

此模式的不足:

  1. **部署包较大:**应用程序包含.NET运行时和所有依赖项,下载大小和硬盘占用空间大于框架依赖版本。
  2. **.NET版本升级复杂:**运行时(随应用分发)只能通过发布新版本应用程序来升级。但.NET会根据运行机器上的框架库需要更新关键安全补丁。

示例演示:

示例1:发布独立的macOS 64位可执行文件,包含.NET运行时

dotnet publish -r osx-x64

生成文件列表:包含macOS 64可执行文件DemoApp及对应macOS 64平台的.NET运行时

示例2:发布独立的Windows 64位可执行文件,包含.NET运行时

dotnet publish -r win-x64

生成文件列表:包含Windows 64可执行文件DemoApp.exe及对应Windows 64平台的.NET运行时

五、框架依赖发布选项详解

框架依赖发布的应用是跨平台的,不包含.NET运行时。应用程序运行需要目标主机单独安装指定版本的.NET运行时。

跨平台二进制文件可使用dotnet <filename.dll>命令运行,适用于任何平台。若应用程序使用具有平台特定实现的NuGet包,所有平台的依赖项都会随应用复制到发布文件夹。

可通过传递-r <RID> --self-contained false参数为特定平台创建可执行文件。省略-r参数则为当前平台创建可执行文件。具有平台特定依赖的NuGet包会复制到发布文件夹。

此模式的优势:

  1. **部署包较小:**仅分发应用程序及其依赖项。.NET运行时和库由用户安装,所有应用共享。
  2. **跨平台:**应用程序和基于.NET的库可在其他操作系统上运行。
  3. **使用最新运行时:**应用程序使用目标系统上安装的最新运行时(在同一主次版本范围内)。这意味着应用会自动使用最新的运行时补丁版本。

此模式的不足:

  1. **需要预装.NET运行时:**仅当主机系统已安装应用目标版本的.NET运行时时,应用才能运行。
  2. **.NET可能变更:**运行时和库可能在运行应用的计算机上更新。

示例演示:

示例1:发布当前平台的框架依赖跨平台应用,不包含.NET运行时,会生成当前平台的可执行文件

dotnet publish

使用dotnet DemoApp.dll可直接运行(本机已安装.NET运行时,DemoApp.dll是跨平台二进制文件

示例2:发布框架依赖的跨平台应用(Linux 64位),不包含.NET运行时,生成Linux 64位可执行文件和DLL文件

dotnet publish -r linux-x64 --self-contained false

使用dotnet DemoApp.dll可直接运行(本机已安装.NET运行时,DemoApp.dll是跨平台二进制文件

六、ReadyToRun编译选项

通过将应用程序程序集编译为ReadyToRun(R2R)格式,可以改善.NET应用程序的启动时间和延迟。R2R是一种提前(AOT)编译形式。

R2R二进制文件通过减少应用程序加载时JIT编译器需要完成的工作量来提升启动性能。与JIT生成的代码相比,二进制文件包含相似的本机代码。

但R2R二进制文件较大,因为它们既包含IL代码(某些情况下仍需要)和同一代码的本机版本。仅当发布针对特定运行时环境(如Linux x64或Windows x64)的应用程序时,R2R才可用。

总结:**通过R2R方式可将代码直接编译为原生代码,减少.NET程序首次加载时JIT编译的性能消耗,提升应用首次加载性能。**类似于ngen的程序集预加载。

对应的发布命令:dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true

以上是.NET 5/.NET Core应用程序发布部署的完整介绍。

推荐参考链接:https://docs.microsoft.com/en-us/dotnet/core/deploying/#publish-framework-dependent

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。