.NET 應用程式發佈概述

本文說明發佈 .NET 應用程式的不同方式。 它涵蓋發佈模式、如何產生可執行檔和跨平台二進位檔,以及每種方法對部署和執行階段環境的影響。 你可以使用 .NET CLI 或 Visual Studio 發佈 .NET 應用程式。

關於發佈的簡短教學,請參見 Tutorial: 發佈.NET控制台應用程式

關於發佈的簡短教學,請參見 Tutorial: 發佈.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/。 不過,您可以選擇為所有建置輸出使用簡化的輸出路徑和資料夾結構。 如需詳細資訊,請參閱 成品輸出配置

這很重要

當你在發佈時跳過建置步驟,透過傳遞 --no-build 參數,使用你建置應用程式時用過的選項,包括目標框架和建置模式。 例如,不要先建立成依賴框架的應用程式,然後再發佈成自包含的應用程式。

在 Visual Studio 中,為每個目標框架建立獨立的發佈設定檔。

可攜式二進位檔

當你發佈 .NET 應用程式時,你可以針對特定平台或建立可攜式二進位檔。 預設情況下,即使在建立可攜式二進位檔時,.NET 也會與可攜式 DLL 一同發布平台專屬的執行檔(「apphost」),除非你明確停用此行為。

建立平台特定的可執行檔是由於屬性 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) 目錄

  1. 右鍵點擊專案方案總管,選擇Publish
  2. 如果這是您第一次發佈,請選取 資料夾 作為發佈目標,然後選取 下一步
  3. 選擇資料夾位置或接受預設值,然後選取 [完成]。
  4. 在發佈設定檔中,選取 [ 顯示所有設定]。
  5. Target Runtime設定為你想要的平台(例如 64 位元 Windows 的 win-x64)。
  6. 選取 儲存 ,然後選取 發佈。

如需執行階段識別碼的清單,請參閱 執行階段識別碼 (RID) 目錄

快速參考

下表提供了如何以 dotnet CLI 發佈應用程式的快速範例:

發佈模式 命令
架構相依部署 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 發佈時,預設模式是依賴框架的部署。 在此模式中,會建立平台特定的可執行檔,可用來啟動您的應用程式。 平台專用的執行檔名稱類似於 Windows 上的 myapp.exe,或在其他平台上稱為 myapp

你的應用程式設定是針對特定版本的 .NET。 目標的 .NET 執行時必須存在於你的應用程式執行的環境中。 舉例來說,如果你的應用程式針對 .NET 9,任何你應用程式執行的環境都必須安裝 .NET 9 執行環境。

發布依賴框架的部署類型會建立一個應用程式,並自動更新至執行應用程式的環境中最新可用的 .NET 安全更新。 欲了解更多編譯時版本綁定的資訊,請參見 選擇使用.NET版本

優點

  • 小型部署:只有應用程式及其相依性會分散。 應用程式執行的環境必須已經安裝了 .NET 執行時。
  • 跨平台:應用程式及任何基於.NET的函式庫可運行於其他作業系統上。
  • 使用最新的修補執行階段:應用程式會使用環境中安裝的最新執行階段。

缺點

  • 需要預先安裝執行時:應用程式只有在目標.NET版本已安裝於環境中時才能執行。
  • .NET 可能會改變:應用程式執行的環境可能會使用較新的 .NET 執行環境,這可能會改變應用程式的行為。

啟動依賴框架的應用程式

有兩種方式可以執行相依於架構的應用程式:透過平台特定的可執行檔 (「apphost」) 和透過 dotnet myapp.dll。 您可以直接執行 apphost 可執行檔,而不是呼叫 dotnet myapp.dll,這仍然是執行應用程式的可接受方式。 只要有可能,建議使用應用程式主機。 使用應用程式主機有許多優點:

  • 可執行檔看起來就像標準原生平台可執行檔一樣。
  • 可執行檔名稱保留在進程名稱中,這意味著可以根據應用程式的名稱輕鬆識別應用程式。
  • 由於 apphost 是原生二進位檔,因此可以附加資訊清單等原生資產。
  • Apphost 預設會套用可用的低階安全性緩解措施,使其更安全。 例如,控制流強制技術(CET)影子堆疊自 .NET 9 起預設啟用。 套用 dotnet 的緩解措施是所有支援執行階段的最小公分母。

發佈

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 建立依賴框架的部署。

  1. 右鍵點擊專案方案總管,選擇Publish
  2. 如果這是您第一次發佈,請選取 資料夾 作為發佈目標,然後選取 下一步
  3. 選擇資料夾位置或接受預設值,然後選取 [完成]。
  4. 在發佈設定檔中,選取 [ 顯示所有設定]。
  5. 部署模式設定相依架構 (這是預設值)。
  6. Target Runtime設定為你想要的平台(例如 64 位元 Windows 的 win-x64)。
  7. 選取 儲存 ,然後選取 發佈。

設定 .NET 安裝搜尋行為

預設情況下,應用程式主機會發現並使用全域安裝的 .NET 執行環境,安裝位置會依平台而異。 如需執行階段探索和安裝位置的詳細資訊,請參閱 針對應用程式啟動失敗進行疑難排解

.NET 執行時路徑也可依執行量進行自訂。 DOTNET_ROOT環境變數可用來指向自訂位置。 欲了解更多關於所有 DOTNET_ROOT 設定選項的資訊,請參閱 .NET 環境變數

一般而言,使用 DOTNET_ROOT 的最佳作法是:

  1. 先清除 DOTNET_ROOT 環境變數,也就是所有以文字 DOTNET_ROOT開頭的環境變數。
  2. DOTNET_ROOT,且僅將DOTNET_ROOT設為目標路徑。
  3. 執行目標應用程式主機。

在 .NET 9 及以後版本中,你可以透過 AppHostDotNetSearchAppHostRelativeDotNet 屬性來設定已發佈執行檔的.NET安裝搜尋路徑。

AppHostDotNetSearch 允許指定一個或多個執行檔尋找.NET安裝的位置:

  • AppLocal:應用程式可執行檔的資料夾
  • AppRelative:相對於應用程式可執行檔的路徑
  • EnvironmentVariable:環境變數的 DOTNET_ROOT[_<arch>]
  • Global已註冊預設 的全域安裝位置

AppHostRelativeDotNet 指定可執行檔的路徑,當 AppHostDotNetSearch 包含 AppRelative 時將進行搜尋。

如需詳細資訊,請參閱 AppHostDotNetSearchAppHostRelativeDotNetapphost 中的安裝位置選項

跨平台 DLL 部署

或者,您可以將應用程式發佈為跨平臺 DLL,而不需要平臺特定的可執行檔。 在此模式中,會在發佈輸出資料夾中建立檔案 myapp.dll 。 若要執行您的應用程式,請導覽至輸出資料夾並使用命令 dotnet myapp.dll

若要發佈為跨平台 DLL:

dotnet publish -c Release -p:UseAppHost=false
  • -c Release

    此參數將組建組態設定為 Release,以針對生產部署進行最佳化。

  • -p:UseAppHost=false

    此屬性會停用建立平臺特定的可執行檔,只產生可攜式 DLL。

  1. 右鍵點擊專案方案總管,選擇Publish
  2. 如果這是您第一次發佈,請選取 資料夾 作為發佈目標,然後選取 下一步
  3. 選擇資料夾位置或接受預設值,然後選取 [完成]。
  4. 在發佈設定檔中,選取 [ 顯示所有設定]。
  5. 部署模式設定架構相依。
  6. 取消勾選 [產生單一檔案]
  7. [目標執行階段] 設定為 [可攜式] (或保留空白)。
  8. 選取 儲存 ,然後選取 發佈。

以自成一體的方式發佈

當您發佈獨立部署 (SCD) 時,發佈程序會建立平台特定的可執行檔。 發佈 SCD 包含所有執行應用程式所需的 .NET 檔案,但不包含 .NET 的原生相依性。 在應用程式執行之前,這些相依性必須存在於環境中。

發佈 SCD 時,生成的應用程式無法自動更新到最新可用的 .NET 安全修補程式。 欲了解更多編譯時版本綁定的資訊,請參見 選擇使用.NET版本

優點

  • Control .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)的執行檔案。

  1. 右鍵點擊專案方案總管,選擇Publish
  2. 如果這是您第一次發佈,請選取 資料夾 作為發佈目標,然後選取 下一步
  3. 選擇資料夾位置或接受預設值,然後選取 [完成]。
  4. 在發佈設定檔中,選取 [ 顯示所有設定]。
  5. 部署模式設定獨立
  6. Target Runtime設定為你想要的平台(例如 64 位元 Windows 的 win-x64)。
  7. 選取 儲存 ,然後選取 發佈。

以單一檔案發佈

當您將應用程式發佈為單一檔案部署時,所有應用程式相依檔案都會組合成單一二進位檔。 此部署模型適用於框架相依和獨立的應用程式,提供了一個有吸引力的選項,可以將應用程式部署和分發為單一檔案。

單一檔案應用程式一律是作業系統和架構特定的。 你需要針對每個配置發佈,例如 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

    此屬性會將所有應用程式相依檔案組合成單一二進位檔。

  1. 右鍵點擊專案方案總管,選擇Publish
  2. 如果這是您第一次發佈,請選取 資料夾 作為發佈目標,然後選取 下一步
  3. 選擇資料夾位置或接受預設值,然後選取 [完成]。
  4. 在發佈設定檔中,選取 [ 顯示所有設定]。
  5. 部署模式設定為獨立架構相依。
  6. Target Runtime設定為你想要的平台(例如 64 位元 Windows 的 win-x64)。
  7. 勾選 產生單一檔案
  8. 選取 儲存 ,然後選取 發佈。

以原生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 發佈介面啟用它。

  1. 方案總管,右鍵點擊你的專案,選擇 編輯專案檔案

  2. 將下列屬性新增至 <PropertyGroup> 中:

    <PublishAot>true</PublishAot>
    
  3. 儲存專案檔。

  4. 右鍵點擊專案方案總管,選擇Publish

  5. 如果這是您第一次發佈,請選取 資料夾 作為發佈目標,然後選取 下一步

  6. 選擇資料夾位置或接受預設值,然後選取 [完成]。

  7. 在發佈設定檔中,選取 [ 顯示所有設定]。

  8. 部署模式設定獨立

  9. Target Runtime設定為你想要的平台(例如 64 位元 Windows 的 win-x64)。

  10. 選取 儲存 ,然後選取 發佈。

如需原生 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 編譯,藉由預先編譯元件來改善啟動效能。

  1. 右鍵點擊專案方案總管,選擇Publish
  2. 如果這是您第一次發佈,請選取 資料夾 作為發佈目標,然後選取 下一步
  3. 選擇資料夾位置或接受預設值,然後選取 [完成]。
  4. 在發佈設定檔中,選取 [ 顯示所有設定]。
  5. 部署模式設定為獨立架構相依。
  6. Target Runtime設定為你想要的平台(例如 64 位元 Windows 的 win-x64)。
  7. 核取 [啟用 ReadyToRun 編譯]。
  8. 選取 儲存 ,然後選取 發佈。

如需 ReadyToRun 部署的詳細資訊,請參閱 ReadyToRun 編譯

容器部署

當你將應用程式發佈為容器時,.NET SDK 會將你的應用程式及其相依性打包成容器映像,無需額外建立 Dockerfile。 此部署模式會建立可在任何容器執行階段 (例如 Docker 或 Podman) 上執行的完整容器映像檔。 容器部署透過消除編寫和維護 Dockerfile 的需求,同時提供最佳化的基礎映像,簡化了容器化過程。

從 .NET SDK 8.0.200 開始,容器支援預設包含,且不需要額外的 NuGet 套件。 對於主控台應用程式,您可能需要透過將EnableSdkContainerSupport屬性設為true以明確啟用容器支援。

提示

欲了解更多與容器相關的專案設定資訊,請參見 Containerize a .NET app reference

優點

  • 簡化容器化:針對基本場景,無需編寫或維護 Dockerfiles。
  • 最佳化基底映像:使用 Microsoft 提供的最佳化基底映像,搭配最新的安全性更新。
  • 一致的環境: 確保在開發、測試和生產中保持一致的運行時環境。
  • 輕鬆分發:容器映像可以輕鬆地在不同環境中共享和部署。
  • 平台隔離:應用程式在隔離的容器中運行,減少了應用程式之間的衝突。

缺點

  • 容器執行階段相依性:目標環境必須安裝容器執行階段。
  • 映像大小:容器映像通常比其他部署方法大。
  • 學習曲線: 需要了解容器概念和工具。
  • 有限的定制: 與自定義 Dockerfile 相比,在複雜場景中靈活性較低。

發佈

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

    此設定檔會觸發容器發佈程式。

  1. 右鍵點擊專案方案總管,選擇Publish
  2. 選取 [Container Registry] 作為發佈目標,然後選取 [ 下一步]。
  3. 選擇你的目標容器登錄檔(例如 Azure Container RegistryDocker Hub,或Generic Registry),並選擇 Next
  4. 設定登錄連線詳細資料和驗證。
  5. 在發佈設定檔中,選取 [ 顯示所有設定]。
  6. 根據您的需求,將部署模式設定為獨立相依於架構
  7. Target Runtime 設定為您想要的平台 (例如,Linux 容器的 linux-x64 )。
  8. 設定容器特定的設定,例如映像名稱和標籤。
  9. 選取 儲存 ,然後選取 發佈。

欲了解更多容器部署資訊,請參閱 .NET SDK 容器建立概述

另請參閱