.net core 3.x 发布单文件
.翻译自:https://github.com/dotnet/designs/blob/master/accepted/2020/single-file/staging.md
NET Core 3.0 中单文件应用程序的设计。
介绍
在 .NET Core 3.0 中实现阶段 1(在暂存文档中所述)对单文件应用的支持。
构建系统接口
可以通过将以下属性添加到应用程序的项目文件来触发发布到单个文件:
<PropertyGroup>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
- 该属性同时应用于框架依赖和自包含的发布操作。
PublishSingleFile
- 该属性适用于特定于平台的生成,与给定的运行时标识符有关。生成的输出是指定平台的本机二进制文件。设置为 时,将保留未定义或设置为 是一个错误。
PublishSingleFile
PublishSingleFile
true
RuntimeIdentifier
UseAppHost
false
- 设置该属性会导致托管应用、托管依赖项、特定于平台的本机依赖项、配置等(基本上在运行时未设置属性的情况下运行发布目录的内容)嵌入到本机 中。
PublishSingleFile
dotnet publish
apphost
默认情况下,符号文件不会嵌入到单文件中,而是作为单独的文件保留在发布目录中。这包括 IL 文件和即用式编译器生成的本机/文件。设置以下属性会导致符号文件包含在单文件中。.pdb
.ni.pdb
app.guid.map
<PropertyGroup>
<IncludeSymbolsInSingleFile>true</IncludeSymbolsInSingleFile>
</PropertyGroup>
通过设置以下元数据,可以显式排除某些文件嵌入到单文件中:
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
例如,要将某些文件放在发布目录中,但不将它们捆绑到单文件中:
<ItemGroup>
<Content Update="*.xml">
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</Content>
</ItemGroup>
捆绑器
捆绑包人是一个工具,将托管应用及其依赖项嵌入到本机可执行文件中,如下所述。下面将介绍 .NET Core 3.x 中的捆绑布局。AppHost
捆绑布局(第 1.0 版) |
---|
AppHost(Bundle-Marker) |
嵌入式文件app.dll app.deps.json app.runtimeconfig.json dependency.dll ... |
捆绑标题 (版本 #) 1.0 #Number of Embedded Files Bundle-ID |
每个捆绑文件的捆绑清单 :( 此信息在 3.0 中不使用) Location (Offset, Size) Type :IL, ReadyToRun, other |
主机
启动时,AppHost 会检查其是否具有嵌入文件。如果是这样,它
- 内存映射整个捆绑包文件。
- 检查内容是否已提取到提取位置(如下所述)
- 如果提取位置中的所有文件都完好无损,则执行将继续重用提取的文件。
- 如果没有,则提取缺少的组件
- 如果提取不可用,主机将嵌入的文件提取到磁盘,如本文档中所述。
- 调用运行时(通过其他主机组件)。
提取位置
对于单文件应用,提取目录为<base>/<app>/<bundle-id>
-
<base>
是DOTNET_BUNDLE_EXTRACT_BASE_DIR
环境变量(如果已设置)。- 如果没有,则默认为:
- 窗户:
%TEMP%\.net
- Unix:
${TMPDIR}/.net/${UID}
如果已设置;如果已设置否则${TMPDIR}
/var/tmp/.net/${UID}
如果存在,并且是可写;否则/var/tmp
/tmp/.net/${UID}
如果存在,并且是可写;否则失败。/tmp
- 窗户:
-
<app>
是单 exe 二进制的名称 -
<bundle-id>
是唯一的捆绑标识符。
API 影响
大多数应用开发对于应用是否以单文件形式发布是不可知的。但是,处理文件物理位置的应用部分需要了解单文件打包。
Assembly.Location
:返回提取位置内的实际位置。AppContext.BaseDirectory
:返回提取目录,其中驻留的位置。app.dll
用户体验
总之,以下是创建 HelloWorld 单文件应用的总体体验
- 创建新的 HelloWorld 应用:
HelloWorld$ dotnet new console
框架依赖HelloWorld
-
正常发布:
dotnet publish
- 发布目录包含主机、应用程序、配置文件 和 PDB 文件。
HelloWorld.exe
HelloWorld.dll
HelloWorld.deps.json
HelloWorld.runtimeconfig.json
HelloWorld.pdb
- 发布目录包含主机、应用程序、配置文件 和 PDB 文件。
-
单文件发布:
dotnet publish -r win10-x64 --self-contained=false /p:PublishSingleFile=true
-
发布目录包含:
HelloWorld.exe
HelloWorld.pdb
-
HelloWorld.dll
中嵌入 和 , 并嵌入 到 中。HelloWorld.deps.json
HelloWorld.runtimeconfig.json
HelloWorld.exe
-
-
运行:
HelloWorld.exe
- 该应用程序完全从单一文件运行,无需中间提取即可归档。
独立世界
-
正常发布:
dotnet publish -r win10-x64
- 发布目录包含 221 个文件,包括主机、应用程序、配置文件、PDB 文件和运行时。
-
单文件发布:
dotnet publish -r win10-x64 /p:PublishSingleFile=true
- 发布目录包含:
HelloWorld.exe
HelloWorld.pdb
- 其余 219 个文件嵌入在主机中。
HelloWorld.exe
- 发布目录包含:
-
运行:
HelloWorld.exe
- 首次运行时,219 个嵌入式文件将在启动时提取到磁盘。
- 应用的后续运行将重用提取,而不会产生启动开销。
调试
在应用的调试和分析方面,预计没有差异。