.翻譯自: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 個嵌入式文件將在啟動時提取到磁盤。
- 應用的后續運行將重用提取,而不會產生啟動開銷。
調試
在應用的調試和分析方面,預計沒有差異。