在 Windows 服務上裝載 ASP.NET Core

ASP.NET Core 應用程式可以裝載在 Windows 上作為 Windows 服務,不需要使用 IIS。 當裝載為 Windows 服務時,應用程式將會在伺服器重新開機後自動啟動。

必要條件

背景工作服務範本

ASP.NET Core 背景工作服務範本提供撰寫長期執行服務應用程式的起點。 使用範本作為 Windows 服務應用程式的基礎:

  1. 從 .NET Core 範本建立背景工作服務應用程式。
  2. 安裝 Microsoft.Extensions.Hosting.WindowsServices NuGet 套件。
  3. 請遵循應用程式組態一節中的指導方針,更新背景工作服務應用程式,以便其執行為 Windows 服務。
  1. 建立新專案。
  2. 選取 [背景工作服務]。 選取 [下一步] 。
  3. 在 [專案名稱] 欄位中提供專案名稱,或接受預設專案名稱。 選取建立
  4. 在 [建立新的背景工作服務] 對話方塊中,選取 [建立]。

應用程式設定

更新 Program.cs 以呼叫 AddWindowsService。 當應用程式以 Windows 服務形式執行,AddWindowsService 會:

  • 將主機存留期設定為 WindowsServiceLifetime
  • 內容根目錄設定為 AppContext.BaseDirectory。 如需詳細資訊,請參閱目前目錄與內容根目錄一節。
  • 啟用記錄至事件記錄檔功能:
    • 應用程式名稱會作為預設來源名稱。
    • 根據呼叫 CreateDefaultBuilder 以建置主機的 ASP.NET Core 範本,應用程式的預設記錄層級為警告或更新版本。
    • appsettings.json/appsettings.{Environment}.json 或其他組態提供者中,使用 Logging:EventLog:LogLevel:Default 索引鍵覆寫預設記錄層級。
    • 只有系統管理員才能建立新的事件來源。 如果無法使用應用程式名稱建立事件來源,則會向「應用程式」來源記錄警告,並停用事件記錄檔。

請考慮下列 ServiceA 類別:

namespace SampleApp.Services;

public class ServiceA : BackgroundService
{
    public ServiceA(ILoggerFactory loggerFactory)
    {
        Logger = loggerFactory.CreateLogger<ServiceA>();
    }

    public ILogger Logger { get; }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        Logger.LogInformation("ServiceA is starting.");

        stoppingToken.Register(() => Logger.LogInformation("ServiceA is stopping."));

        while (!stoppingToken.IsCancellationRequested)
        {
            Logger.LogInformation("ServiceA is doing background work.");

            await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
        }

        Logger.LogInformation("ServiceA has stopped.");
    }
}

下列 Program.cs 呼叫 AddHostedService 來註冊 ServiceA

using SampleApp.Services;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();

builder.Services.AddWindowsService();
builder.Services.AddHostedService<ServiceA>();

var app = builder.Build();

app.MapRazorPages();

app.Run();

本主題隨附下列範例應用程式:

  • 背景工作服務範例:以背景工作服務範本為基礎的非 Web 應用程式範例,該範本使用託管服務來執行背景工作。
  • Web 應用程式服務範例:以 Windows 服務形式執行的 Razor Pages Web 應用程式範例,其包含用於背景工作的託管服務

如需 MVC 指引,請參閱 ASP.NET Core MVC 概觀從 ASP.NET Core 2.2 移轉到 3.0 底下的文章。

部署類型

如需詳細資訊與部署案例建議,請參閱 .NET Core 應用程式部署

SDK

對於使用 Razor Pages 或 MVC 架構的 Web 應用程式型服務,請在專案檔中指定 Web SDK:

<Project Sdk="Microsoft.NET.Sdk.Web">

如果服務只執行背景工作 (例如託管服務),請在專案檔中指定背景工作 SDK:

<Project Sdk="Microsoft.NET.Sdk.Worker">

架構相依部署 (FDD)

架構相依部署 (FDD) 仰賴存在於目標系統上的全系統共用 .NET Core 版本。 依照此文章中的指導方針採用 FDD 案例時,SDK 會產生可執行檔 (.exe),稱為「架構相依可執行檔」

如果使用 Web SDK,Windows Services 應用程式不需要 web.config 檔案 (發行 ASP.NET Core 應用程式時通常會產生此檔案)。 若要停用 web.config 檔案的建立,請新增 <IsTransformWebConfigDisabled> 屬性集到 true

<PropertyGroup>
  <TargetFramework>net7.0</TargetFramework>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

自封式部署 (SCD)

自封式部署 (SCD) 不仰賴任何存在於主機系統上的共用架構。 執行階段與應用程式的相依性會隨著應用程式進行部署。

Windows 執行階段識別碼 (RID) 會納入包含目標 Framework 的 <PropertyGroup> 中:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

發行多個 RID:

如需詳細資訊,請參閱 .NET Core RID 目錄

服務使用者帳戶

若要為服務建立使用者帳戶,請從系統管理 PowerShell 6 命令殼層使用 New-LocalUser Cmdlet。

Windows 10 2018 年 10 月更新 (版本 1809/組建 10.0.17763) 或更新版本:

New-LocalUser -Name {SERVICE NAME}

在 Windows 10 2018 年 10 月更新之前 (1809 版/組建 10.0.17763) 的 Windows OS 上:

powershell -Command "New-LocalUser -Name {SERVICE NAME}"

在系統提示時提供強式密碼

除非搭配過期 DateTime-AccountExpires 參數提供給 New-LocalUser Cmdlet,否則該帳戶將不會過期。

如需詳細資訊,請參閱 Microsoft.PowerShell.LocalAccounts服務使用者帳戶

使用 Active Directory 時有一個管理使用者的替代方法,就是使用「受控服務帳戶」。 如需詳細資訊,請參閱群組受控服務帳戶概觀

以服務方式登入權限

若要為服務使用者帳戶建立「以服務方式登入」權限:

  1. 執行 secpol.msc 來開啟 [本機安全性原則編輯器]。
  2. 展開 [本機原則] 節點,然後選取 [使用者權限指派]
  3. 開啟 [以服務方式登入] 原則。
  4. 選取 [新增使用者或群組]
  5. 使用下列其中一種方法提供物件名稱 (使用者帳戶):
    1. 在物件名稱欄位中輸入使用者帳戶 ({DOMAIN OR COMPUTER NAME\USER}),然後選取 [確定] 將使用者新增至原則。
    2. 選取進階。 選取 [立即尋找]。 從清單中選取使用者帳戶。 選取 [確定]。 再次選取 [確定] 將使用者新增至原則。
  6. 選取 [確定] 或 [套用] 以接受變更。

建立及管理 Windows 服務

建立服務

使用 PowerShell 命令來註冊服務。 透過系統管理 PowerShell 6 命令殼層,執行下列命令:

$acl = Get-Acl "{EXE PATH}"
$aclRuleArgs = "{DOMAIN OR COMPUTER NAME\USER}", "Read,Write,ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($aclRuleArgs)
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "{EXE PATH}"

New-Service -Name {SERVICE NAME} -BinaryPathName "{EXE FILE PATH} --contentRoot {EXE FOLDER PATH}" -Credential "{DOMAIN OR COMPUTER NAME\USER}" -Description "{DESCRIPTION}" -DisplayName "{DISPLAY NAME}" -StartupType Automatic
  • {EXE PATH}:應用程式可執行檔在主機上的路徑 (例如 d:\myservice)。 請勿在路徑中包含應用程式可執行檔的檔案名稱。 不需要結尾的斜線。
  • {DOMAIN OR COMPUTER NAME\USER}:服務使用者帳戶 (例如 Contoso\ServiceUser)。
  • {SERVICE NAME}:服務名稱 (例如 MyService)。
  • {EXE FILE PATH}:應用程式的完整可執行檔路徑 (例如 d:\myservice\myservice.exe)。 包含可執行檔的檔案名稱 (包含副檔名)。
  • {EXE FOLDER PATH}:應用程式的完整可執行資料夾路徑 (例如 d:\myservice)。
  • {DESCRIPTION}:服務描述 (例如 My sample service)。
  • {DISPLAY NAME}:服務顯示名稱 (例如 My Service)。

啟動服務

以下列 PowerShell 6 命令啟動服務:

Start-Service -Name {SERVICE NAME}

此命令需要幾秒鐘啓動服務。

判斷服務的狀態

若要檢查服務狀態,請使用下列 PowerShell 6 命令:

Get-Service -Name {SERVICE NAME}

狀態會回報為下列值之一:

  • Starting
  • Running
  • Stopping
  • Stopped

停止服務

使用下列 PowerShell 6 命令停止服務:

Stop-Service -Name {SERVICE NAME}

移除服務

在停止服務的短暫延遲之後,請以下列 PowerShell 6 命令移除服務:

Remove-Service -Name {SERVICE NAME}

Proxy 伺服器和負載平衡器案例

服務如果會與來自網際網路或公司網路的要求進行互動,並且位於 Proxy 或負載平衡器後方,可能會需要額外的設定。 如需詳細資訊,請參閱設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器

設定端點

ASP.NET Core 預設會繫結至 http://localhost:5000。 透過設定 ASPNETCORE_URLS 環境變數來設定 URL 和連接埠。

如需其他 URL 和連接埠組態方法,請參閱相關的伺服器文章:

上述指引涵蓋了 HTTPS 端點的支援。 例如,在搭配 Windows 服務使用驗證時,針對 HTTPS 設定應用程式。

注意

不支援使用 ASP.NET Core HTTPS 開發憑證來保護服務端點。

目前目錄和內容根目錄

針對 Windows 服務呼叫 GetCurrentDirectory 所傳回的目前工作目錄為 C:\WINDOWS\system32 資料夾。 System32 資料夾不是儲存服務檔案 (例如,設定檔) 的合適位置。 使用下列其中一個方式來維護及存取服務的資產與設定檔。

使用 ContentRootPath 或 ContentRootFileProvider

使用 IHostEnvironment.ContentRootPathContentRootFileProvider 來找出應用程式的資源。

當應用程式以服務的形式執行時,UseWindowsService 會將 ContentRootPath 設定為 AppContext.BaseDirectory

應用程式的預設設定檔 appsettings.jsonappsettings.{Environment}.json 會藉由在主機建構期間呼叫CreateDefaultBuilder,從應用程式的內容根目錄中載入。

對於 ConfigureAppConfiguration 中開發人員程式碼所載入的其他設定檔,不需要呼叫 SetBasePath。 在下列範例中,custom_settings.json 檔案存在於應用程式的內容根目錄中,而且載入時不會明確設定基本路徑:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("custom_settings.json");
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

請勿嘗試使用 GetCurrentDirectory 來取得資源路徑,因為 Windows 服務應用程式會傳回 C:\WINDOWS\system32 資料夾作為其目前目錄。

將服務的檔案儲存在磁碟上的適當位置

使用包含檔案的 IConfigurationBuilder 資料夾,使用 SetBasePath 來指定絕對路徑。

疑難排解

若要針對 Windows 服務應用程式進行疑難排解,請參閱針對 ASP.NET Core 專案進行疑難排解和偵錯

常見錯誤

  • 正在使用舊版或發行前版本的 PowerShell。
  • 已註冊的服務不會使用來自 dotnet publish 命令的應用程式已發行輸出。 應用程式部署不支援 dotnet build 命令的輸出。 根據部署類型,在下列其中一個資料夾中找到已發行的資產:
    • bin/Release/{TARGET FRAMEWORK}/publish (FDD)
    • bin/Release/{TARGET FRAMEWORK}/{RUNTIME IDENTIFIER}/publish (SCD)
  • 服務未處於「執行中」狀態。
  • 應用程式使用的資源路徑 (例如憑證) 不正確。 Windows 服務的基底路徑為 c:\Windows\System32
  • 使用者沒有以服務方式登入 的權限。
  • 執行 New-Service PowerShell 命令時,使用者的密碼已過期或以不正確的方式傳遞。
  • 應用程式須使用 ASP.NET Core 驗證,但並未針對安全連線 (HTTPS) 設定。
  • 要求 URL 連接埠不正確或未在應用程式中正確設定。

系統和應用程式事件記錄檔

存取系統和應用程式事件記錄檔:

  1. 開啟 [開始] 功能表,搜尋事件檢視器,然後選取 [事件檢視器] 應用程式。
  2. 在 [事件檢視器] 中,開啟 [Windows 記錄] 節點。
  3. 選取 [系統] 以開啟 [系統事件記錄檔]。 選取 [應用程式] 以開啟「應用程式事件記錄檔」。
  4. 搜尋與失敗應用程式相關的錯誤。

在命令提示字元中執行應用程式

許多啟動錯誤不會在事件記錄檔中產生實用的資訊。 您可以藉由在主控系統上的命令提示字元中執行應用程式,來找出一些錯誤的原因。 若要從應用程式記錄其他詳細資料,請降低記錄層級,或在開發環境中執行應用程式。

清除套件快取

在升級開發電腦上的 .NET Core SDK 或變更應用程式內的套件版本之後,正常運作的應用程式便立即發生失敗。 在某些情況下,執行主要升級時,不一致的套件可能會中斷應用程式。 大多數這些問題都可依照下列指示來進行修正:

  1. 刪除 [bin] 和 [obj] 資料夾。

  2. 您可以從命令殼層執行 dotnet nuget locals all --clear 來清除套件快取。

    您也可以使用 nuget.exe 工具並執行 nuget locals all -clear 命令,來清除套件快取。 nuget.exe 並未隨附在 Windows 桌面作業系統的安裝中,必須另外從 NuGet 網站取得。

  3. 還原並重建專案。

  4. 在重新部署應用程式之前,請先刪除伺服器上部署資料夾中的所有檔案。

應用程式緩慢或沒有回應

「損毀傾印」是系統記憶體的快照集,可協助您判斷應用程式損毀、啟動失敗或應用程式緩慢的原因。

應用程式損毀或發生例外狀況

Windows 錯誤報告 (WER) 取得並分析傾印:

  1. c:\dumps 中建立資料夾以保存損毀傾印檔案。

  2. 使用應用程式可執行檔名稱執行 EnableDumps PowerShell 指令碼

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. 在會導致損毀的情況下,執行應用程式。

  4. 發生損毀之後,請執行 DisableDumps PowerShell 指令碼

    .\DisableDumps {APPLICATION EXE}
    

在應用程式損毀且傾印收集完成之後,即可正常結束應用程式。 PowerShell 指令碼會將 WER 設定為每個應用程式收集最多五個傾印。

警告

損毀傾印可能會佔用大量磁碟空間 (每個高達好幾 GB)。

應用程式沒有回應、在啟動期間失敗或正常執行

當應用程式停止回應 (停止回應但不會當機)、在啟動期間失敗或正常執行時,請參閱使用者模式傾印檔案:選擇最佳工具以選取適當的工具來產生傾印。

分析傾印

您可以使用數種方法來分析傾印。 如需詳細資訊,請參閱分析使用者模式傾印檔案

其他資源

ASP.NET Core 應用程式可以裝載在 Windows 上作為 Windows 服務,不需要使用 IIS。 當裝載為 Windows 服務時,應用程式將會在伺服器重新開機後自動啟動。

檢視或下載範例程式碼 \(英文\) (如何下載)

必要條件

背景工作服務範本

ASP.NET Core 背景工作服務範本提供撰寫長期執行服務應用程式的起點。 使用範本作為 Windows 服務應用程式的基礎:

  1. 從 .NET Core 範本建立背景工作服務應用程式。
  2. 請遵循應用程式組態一節中的指導方針,更新背景工作服務應用程式,以便其執行為 Windows 服務。
  1. 建立新專案。
  2. 選取 [背景工作服務]。 選取 [下一步] 。
  3. 在 [專案名稱] 欄位中提供專案名稱,或接受預設專案名稱。 選取建立
  4. 在 [建立新的背景工作服務] 對話方塊中,選取 [建立]。

應用程式設定

應用程式需要 Microsoft.Extensions.Hosting.WindowsServices 的套件參考。

IHostBuilder.UseWindowsService 會在建置主機時呼叫。 如果應用程式以 Windows 服務形式執行,則方法會:

  • 將主機存留期設定為 WindowsServiceLifetime
  • 內容根目錄設定為 AppContext.BaseDirectory。 如需詳細資訊,請參閱目前目錄與內容根目錄一節。
  • 啟用記錄至事件記錄檔功能:
    • 應用程式名稱會作為預設來源名稱。
    • 根據呼叫 CreateDefaultBuilder 以建置主機的 ASP.NET Core 範本,應用程式的預設記錄層級為警告或更新版本。
    • appsettings.json/appsettings.{Environment}.json 或其他組態提供者中,使用 Logging:EventLog:LogLevel:Default 索引鍵覆寫預設記錄層級。
    • 只有系統管理員才能建立新的事件來源。 如果無法使用應用程式名稱建立事件來源,則會向「應用程式」來源記錄警告,並停用事件記錄檔。

Program.cs 中:

  • 設定 ContentRootPath
  • 呼叫 UseWindowsService
using Microsoft.Extensions.Hosting.WindowsServices;
using SampleApp.Services;

var options = new WebApplicationOptions
{
    Args = args,
    ContentRootPath = WindowsServiceHelpers.IsWindowsService() 
                                     ? AppContext.BaseDirectory : default
};

var builder = WebApplication.CreateBuilder(options);
builder.Services.AddRazorPages();
builder.Services.AddHostedService<ServiceA>();
builder.Services.AddHostedService<ServiceB>();

builder.Host.UseWindowsService();

var app = builder.Build();

app.UseStaticFiles();
app.UseRouting();
app.MapRazorPages();
await app.RunAsync();

本主題隨附下列範例應用程式:

  • 背景工作服務範例:以背景工作服務範本為基礎的非 Web 應用程式範例,該範本使用託管服務來執行背景工作。
  • Web 應用程式服務範例:以 Windows 服務形式執行的 Razor Pages Web 應用程式範例,其包含用於背景工作的託管服務

如需 MVC 指引,請參閱 ASP.NET Core MVC 概觀從 ASP.NET Core 2.2 移轉到 3.0 底下的文章。

部署類型

如需詳細資訊與部署案例建議,請參閱 .NET Core 應用程式部署

SDK

對於使用 Razor Pages 或 MVC 架構的 Web 應用程式型服務,請在專案檔中指定 Web SDK:

<Project Sdk="Microsoft.NET.Sdk.Web">

如果服務只執行背景工作 (例如託管服務),請在專案檔中指定背景工作 SDK:

<Project Sdk="Microsoft.NET.Sdk.Worker">

架構相依部署 (FDD)

架構相依部署 (FDD) 仰賴存在於目標系統上的全系統共用 .NET Core 版本。 依照此文章中的指導方針採用 FDD 案例時,SDK 會產生可執行檔 (.exe),稱為「架構相依可執行檔」

如果使用 Web SDK,Windows Services 應用程式不需要 web.config 檔案 (發行 ASP.NET Core 應用程式時通常會產生此檔案)。 若要停用 web.config 檔案的建立,請新增 <IsTransformWebConfigDisabled> 屬性集到 true

<PropertyGroup>
  <TargetFramework>net6.0</TargetFramework>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

自封式部署 (SCD)

自封式部署 (SCD) 不仰賴任何存在於主機系統上的共用架構。 執行階段與應用程式的相依性會隨著應用程式進行部署。

Windows 執行階段識別碼 (RID) 會納入包含目標 Framework 的 <PropertyGroup> 中:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

發行多個 RID:

如需詳細資訊,請參閱 .NET Core RID 目錄

服務使用者帳戶

若要為服務建立使用者帳戶,請從系統管理 PowerShell 6 命令殼層使用 New-LocalUser Cmdlet。

Windows 10 2018 年 10 月更新 (版本 1809/組建 10.0.17763) 或更新版本:

New-LocalUser -Name {SERVICE NAME}

在 Windows 10 2018 年 10 月更新之前 (1809 版/組建 10.0.17763) 的 Windows OS 上:

powershell -Command "New-LocalUser -Name {SERVICE NAME}"

在系統提示時提供強式密碼

除非搭配過期 DateTime-AccountExpires 參數提供給 New-LocalUser Cmdlet,否則該帳戶將不會過期。

如需詳細資訊,請參閱 Microsoft.PowerShell.LocalAccounts服務使用者帳戶

使用 Active Directory 時有一個管理使用者的替代方法,就是使用「受控服務帳戶」。 如需詳細資訊,請參閱群組受控服務帳戶概觀

以服務方式登入權限

若要為服務使用者帳戶建立「以服務方式登入」權限:

  1. 執行 secpol.msc 來開啟 [本機安全性原則編輯器]。
  2. 展開 [本機原則] 節點,然後選取 [使用者權限指派]
  3. 開啟 [以服務方式登入] 原則。
  4. 選取 [新增使用者或群組]
  5. 使用下列其中一種方法提供物件名稱 (使用者帳戶):
    1. 在物件名稱欄位中輸入使用者帳戶 ({DOMAIN OR COMPUTER NAME\USER}),然後選取 [確定] 將使用者新增至原則。
    2. 選取進階。 選取 [立即尋找]。 從清單中選取使用者帳戶。 選取 [確定]。 再次選取 [確定] 將使用者新增至原則。
  6. 選取 [確定] 或 [套用] 以接受變更。

建立及管理 Windows 服務

建立服務

使用 PowerShell 命令來註冊服務。 透過系統管理 PowerShell 6 命令殼層,執行下列命令:

$acl = Get-Acl "{EXE PATH}"
$aclRuleArgs = "{DOMAIN OR COMPUTER NAME\USER}", "Read,Write,ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($aclRuleArgs)
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "{EXE PATH}"

New-Service -Name {SERVICE NAME} -BinaryPathName "{EXE FILE PATH} --contentRoot {EXE FOLDER PATH}" -Credential "{DOMAIN OR COMPUTER NAME\USER}" -Description "{DESCRIPTION}" -DisplayName "{DISPLAY NAME}" -StartupType Automatic
  • {EXE PATH}:應用程式可執行檔在主機上的路徑 (例如 d:\myservice)。 請勿在路徑中包含應用程式可執行檔的檔案名稱。 不需要結尾的斜線。
  • {DOMAIN OR COMPUTER NAME\USER}:服務使用者帳戶 (例如 Contoso\ServiceUser)。
  • {SERVICE NAME}:服務名稱 (例如 MyService)。
  • {EXE FILE PATH}:應用程式的完整可執行檔路徑 (例如 d:\myservice\myservice.exe)。 包含可執行檔的檔案名稱 (包含副檔名)。
  • {EXE FOLDER PATH}:應用程式的完整可執行資料夾路徑 (例如 d:\myservice)。
  • {DESCRIPTION}:服務描述 (例如 My sample service)。
  • {DISPLAY NAME}:服務顯示名稱 (例如 My Service)。

啟動服務

以下列 PowerShell 6 命令啟動服務:

Start-Service -Name {SERVICE NAME}

此命令需要幾秒鐘啓動服務。

判斷服務的狀態

若要檢查服務狀態,請使用下列 PowerShell 6 命令:

Get-Service -Name {SERVICE NAME}

狀態會回報為下列值之一:

  • Starting
  • Running
  • Stopping
  • Stopped

停止服務

使用下列 PowerShell 6 命令停止服務:

Stop-Service -Name {SERVICE NAME}

移除服務

在停止服務的短暫延遲之後,請以下列 PowerShell 6 命令移除服務:

Remove-Service -Name {SERVICE NAME}

Proxy 伺服器和負載平衡器案例

服務如果會與來自網際網路或公司網路的要求進行互動,並且位於 Proxy 或負載平衡器後方,可能會需要額外的設定。 如需詳細資訊,請參閱設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器

設定端點

ASP.NET Core 預設會繫結至 http://localhost:5000。 透過設定 ASPNETCORE_URLS 環境變數來設定 URL 和連接埠。

如需其他 URL 和連接埠組態方法,請參閱相關的伺服器文章:

上述指引涵蓋了 HTTPS 端點的支援。 例如,在搭配 Windows 服務使用驗證時,針對 HTTPS 設定應用程式。

注意

不支援使用 ASP.NET Core HTTPS 開發憑證來保護服務端點。

目前目錄和內容根目錄

針對 Windows 服務呼叫 GetCurrentDirectory 所傳回的目前工作目錄為 C:\WINDOWS\system32 資料夾。 System32 資料夾不是儲存服務檔案 (例如,設定檔) 的合適位置。 使用下列其中一個方式來維護及存取服務的資產與設定檔。

使用 ContentRootPath 或 ContentRootFileProvider

使用 IHostEnvironment.ContentRootPathContentRootFileProvider 來找出應用程式的資源。

當應用程式以服務的形式執行時,UseWindowsService 會將 ContentRootPath 設定為 AppContext.BaseDirectory

應用程式的預設設定檔 appsettings.jsonappsettings.{Environment}.json 會藉由在主機建構期間呼叫CreateDefaultBuilder,從應用程式的內容根目錄中載入。

對於 ConfigureAppConfiguration 中開發人員程式碼所載入的其他設定檔,不需要呼叫 SetBasePath。 在下列範例中,custom_settings.json 檔案存在於應用程式的內容根目錄中,而且載入時不會明確設定基本路徑:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("custom_settings.json");
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

請勿嘗試使用 GetCurrentDirectory 來取得資源路徑,因為 Windows 服務應用程式會傳回 C:\WINDOWS\system32 資料夾作為其目前目錄。

將服務的檔案儲存在磁碟上的適當位置

使用包含檔案的 IConfigurationBuilder 資料夾,使用 SetBasePath 來指定絕對路徑。

疑難排解

若要針對 Windows 服務應用程式進行疑難排解,請參閱針對 ASP.NET Core 專案進行疑難排解和偵錯

常見錯誤

  • 正在使用舊版或發行前版本的 PowerShell。
  • 已註冊的服務不會使用來自 dotnet publish 命令的應用程式已發行輸出。 應用程式部署不支援 dotnet build 命令的輸出。 根據部署類型,在下列其中一個資料夾中找到已發行的資產:
    • bin/Release/{TARGET FRAMEWORK}/publish (FDD)
    • bin/Release/{TARGET FRAMEWORK}/{RUNTIME IDENTIFIER}/publish (SCD)
  • 服務未處於「執行中」狀態。
  • 應用程式使用的資源路徑 (例如憑證) 不正確。 Windows 服務的基底路徑為 c:\Windows\System32
  • 使用者沒有以服務方式登入 的權限。
  • 執行 New-Service PowerShell 命令時,使用者的密碼已過期或以不正確的方式傳遞。
  • 應用程式須使用 ASP.NET Core 驗證,但並未針對安全連線 (HTTPS) 設定。
  • 要求 URL 連接埠不正確或未在應用程式中正確設定。

系統和應用程式事件記錄檔

存取系統和應用程式事件記錄檔:

  1. 開啟 [開始] 功能表,搜尋事件檢視器,然後選取 [事件檢視器] 應用程式。
  2. 在 [事件檢視器] 中,開啟 [Windows 記錄] 節點。
  3. 選取 [系統] 以開啟 [系統事件記錄檔]。 選取 [應用程式] 以開啟「應用程式事件記錄檔」。
  4. 搜尋與失敗應用程式相關的錯誤。

在命令提示字元中執行應用程式

許多啟動錯誤不會在事件記錄檔中產生實用的資訊。 您可以藉由在主控系統上的命令提示字元中執行應用程式,來找出一些錯誤的原因。 若要從應用程式記錄其他詳細資料,請降低記錄層級,或在開發環境中執行應用程式。

清除套件快取

在升級開發電腦上的 .NET Core SDK 或變更應用程式內的套件版本之後,正常運作的應用程式便立即發生失敗。 在某些情況下,執行主要升級時,不一致的套件可能會中斷應用程式。 大多數這些問題都可依照下列指示來進行修正:

  1. 刪除 [bin] 和 [obj] 資料夾。

  2. 您可以從命令殼層執行 dotnet nuget locals all --clear 來清除套件快取。

    您也可以使用 nuget.exe 工具並執行 nuget locals all -clear 命令,來清除套件快取。 nuget.exe 並未隨附在 Windows 桌面作業系統的安裝中,必須另外從 NuGet 網站取得。

  3. 還原並重建專案。

  4. 在重新部署應用程式之前,請先刪除伺服器上部署資料夾中的所有檔案。

應用程式緩慢或沒有回應

「損毀傾印」是系統記憶體的快照集,可協助您判斷應用程式損毀、啟動失敗或應用程式緩慢的原因。

應用程式損毀或發生例外狀況

Windows 錯誤報告 (WER) 取得並分析傾印:

  1. c:\dumps 中建立資料夾以保存損毀傾印檔案。

  2. 使用應用程式可執行檔名稱執行 EnableDumps PowerShell 指令碼

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. 在會導致損毀的情況下,執行應用程式。

  4. 發生損毀之後,請執行 DisableDumps PowerShell 指令碼

    .\DisableDumps {APPLICATION EXE}
    

在應用程式損毀且傾印收集完成之後,即可正常結束應用程式。 PowerShell 指令碼會將 WER 設定為每個應用程式收集最多五個傾印。

警告

損毀傾印可能會佔用大量磁碟空間 (每個高達好幾 GB)。

應用程式沒有回應、在啟動期間失敗或正常執行

當應用程式停止回應 (停止回應但不會當機)、在啟動期間失敗或正常執行時,請參閱使用者模式傾印檔案:選擇最佳工具以選取適當的工具來產生傾印。

分析傾印

您可以使用數種方法來分析傾印。 如需詳細資訊,請參閱分析使用者模式傾印檔案

其他資源

ASP.NET Core 應用程式可以裝載在 Windows 上作為 Windows 服務,不需要使用 IIS。 當裝載為 Windows 服務時,應用程式將會在伺服器重新開機後自動啟動。

檢視或下載範例程式碼 \(英文\) (如何下載)

必要條件

背景工作服務範本

ASP.NET Core 背景工作服務範本提供撰寫長期執行服務應用程式的起點。 使用範本作為 Windows 服務應用程式的基礎:

  1. 從 .NET Core 範本建立背景工作服務應用程式。
  2. 請遵循應用程式組態一節中的指導方針,更新背景工作服務應用程式,以便其執行為 Windows 服務。
  1. 建立新專案。
  2. 選取 [背景工作服務]。 選取 [下一步] 。
  3. 在 [專案名稱] 欄位中提供專案名稱,或接受預設專案名稱。 選取建立
  4. 在 [建立新的背景工作服務] 對話方塊中,選取 [建立]。

應用程式設定

應用程式需要 Microsoft.Extensions.Hosting.WindowsServices 的套件參考。

IHostBuilder.UseWindowsService 會在建置主機時呼叫。 如果應用程式以 Windows 服務形式執行,則方法會:

  • 將主機存留期設定為 WindowsServiceLifetime
  • 內容根目錄設定為 AppContext.BaseDirectory。 如需詳細資訊,請參閱目前目錄與內容根目錄一節。
  • 啟用記錄至事件記錄檔功能:
    • 應用程式名稱會作為預設來源名稱。
    • 根據呼叫 CreateDefaultBuilder 以建置主機的 ASP.NET Core 範本,應用程式的預設記錄層級為警告或更新版本。
    • appsettings.json/appsettings.{Environment}.json 或其他組態提供者中,使用 Logging:EventLog:LogLevel:Default 索引鍵覆寫預設記錄層級。
    • 只有系統管理員才能建立新的事件來源。 如果無法使用應用程式名稱建立事件來源,則會向「應用程式」來源記錄警告,並停用事件記錄檔。

Program.csCreateHostBuilder 中:

Host.CreateDefaultBuilder(args)
    .UseWindowsService()
    ...

本主題隨附下列範例應用程式:

  • 背景工作服務範例:以背景工作服務範本為基礎的非 Web 應用程式範例,該範本使用託管服務來執行背景工作。
  • Web 應用程式服務範例:以 Windows 服務形式執行的 Razor Pages Web 應用程式範例,其包含用於背景工作的託管服務

如需 MVC 指引,請參閱 ASP.NET Core MVC 概觀從 ASP.NET Core 2.2 移轉到 3.0 底下的文章。

部署類型

如需詳細資訊與部署案例建議,請參閱 .NET Core 應用程式部署

SDK

對於使用 Razor Pages 或 MVC 架構的 Web 應用程式型服務,請在專案檔中指定 Web SDK:

<Project Sdk="Microsoft.NET.Sdk.Web">

如果服務只執行背景工作 (例如託管服務),請在專案檔中指定背景工作 SDK:

<Project Sdk="Microsoft.NET.Sdk.Worker">

架構相依部署 (FDD)

架構相依部署 (FDD) 仰賴存在於目標系統上的全系統共用 .NET Core 版本。 依照此文章中的指導方針採用 FDD 案例時,SDK 會產生可執行檔 (.exe),稱為「架構相依可執行檔」

如果使用 Web SDK,Windows Services 應用程式不需要 web.config 檔案 (發行 ASP.NET Core 應用程式時通常會產生此檔案)。 若要停用 web.config 檔案的建立,請新增 <IsTransformWebConfigDisabled> 屬性集到 true

<PropertyGroup>
  <TargetFramework>netcoreapp3.0</TargetFramework>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

自封式部署 (SCD)

自封式部署 (SCD) 不仰賴任何存在於主機系統上的共用架構。 執行階段與應用程式的相依性會隨著應用程式進行部署。

Windows 執行階段識別碼 (RID) 會納入包含目標 Framework 的 <PropertyGroup> 中:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

發行多個 RID:

如需詳細資訊,請參閱 .NET Core RID 目錄

服務使用者帳戶

若要為服務建立使用者帳戶,請從系統管理 PowerShell 6 命令殼層使用 New-LocalUser Cmdlet。

Windows 10 2018 年 10 月更新 (版本 1809/組建 10.0.17763) 或更新版本:

New-LocalUser -Name {SERVICE NAME}

在 Windows 10 2018 年 10 月更新之前 (1809 版/組建 10.0.17763) 的 Windows OS 上:

powershell -Command "New-LocalUser -Name {SERVICE NAME}"

在系統提示時提供強式密碼

除非搭配過期 DateTime-AccountExpires 參數提供給 New-LocalUser Cmdlet,否則該帳戶將不會過期。

如需詳細資訊,請參閱 Microsoft.PowerShell.LocalAccounts服務使用者帳戶

使用 Active Directory 時有一個管理使用者的替代方法,就是使用「受控服務帳戶」。 如需詳細資訊,請參閱群組受控服務帳戶概觀

以服務方式登入權限

若要為服務使用者帳戶建立「以服務方式登入」權限:

  1. 執行 secpol.msc 來開啟 [本機安全性原則編輯器]。
  2. 展開 [本機原則] 節點,然後選取 [使用者權限指派]
  3. 開啟 [以服務方式登入] 原則。
  4. 選取 [新增使用者或群組]
  5. 使用下列其中一種方法提供物件名稱 (使用者帳戶):
    1. 在物件名稱欄位中輸入使用者帳戶 ({DOMAIN OR COMPUTER NAME\USER}),然後選取 [確定] 將使用者新增至原則。
    2. 選取進階。 選取 [立即尋找]。 從清單中選取使用者帳戶。 選取 [確定]。 再次選取 [確定] 將使用者新增至原則。
  6. 選取 [確定] 或 [套用] 以接受變更。

建立及管理 Windows 服務

建立服務

使用 PowerShell 命令來註冊服務。 透過系統管理 PowerShell 6 命令殼層,執行下列命令:

$acl = Get-Acl "{EXE PATH}"
$aclRuleArgs = "{DOMAIN OR COMPUTER NAME\USER}", "Read,Write,ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($aclRuleArgs)
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "{EXE PATH}"

New-Service -Name {SERVICE NAME} -BinaryPathName "{EXE FILE PATH}" -Credential "{DOMAIN OR COMPUTER NAME\USER}" -Description "{DESCRIPTION}" -DisplayName "{DISPLAY NAME}" -StartupType Automatic
  • {EXE PATH}:應用程式可執行檔在主機上的路徑 (例如 d:\myservice)。 請勿在路徑中包含應用程式可執行檔的檔案名稱。 不需要結尾的斜線。
  • {DOMAIN OR COMPUTER NAME\USER}:服務使用者帳戶 (例如 Contoso\ServiceUser)。
  • {SERVICE NAME}:服務名稱 (例如 MyService)。
  • {EXE FILE PATH}:應用程式的完整可執行檔路徑 (例如 d:\myservice\myservice.exe)。 包含可執行檔的檔案名稱 (包含副檔名)。
  • {DESCRIPTION}:服務描述 (例如 My sample service)。
  • {DISPLAY NAME}:服務顯示名稱 (例如 My Service)。

啟動服務

以下列 PowerShell 6 命令啟動服務:

Start-Service -Name {SERVICE NAME}

此命令需要幾秒鐘啓動服務。

判斷服務的狀態

若要檢查服務狀態,請使用下列 PowerShell 6 命令:

Get-Service -Name {SERVICE NAME}

狀態會回報為下列值之一:

  • Starting
  • Running
  • Stopping
  • Stopped

停止服務

使用下列 PowerShell 6 命令停止服務:

Stop-Service -Name {SERVICE NAME}

移除服務

在停止服務的短暫延遲之後,請以下列 PowerShell 6 命令移除服務:

Remove-Service -Name {SERVICE NAME}

Proxy 伺服器和負載平衡器案例

服務如果會與來自網際網路或公司網路的要求進行互動,並且位於 Proxy 或負載平衡器後方,可能會需要額外的設定。 如需詳細資訊,請參閱設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器

設定端點

ASP.NET Core 預設會繫結至 http://localhost:5000。 透過設定 ASPNETCORE_URLS 環境變數來設定 URL 和連接埠。

如需其他 URL 和連接埠組態方法,請參閱相關的伺服器文章:

上述指引涵蓋了 HTTPS 端點的支援。 例如,在搭配 Windows 服務使用驗證時,針對 HTTPS 設定應用程式。

注意

不支援使用 ASP.NET Core HTTPS 開發憑證來保護服務端點。

目前目錄和內容根目錄

針對 Windows 服務呼叫 GetCurrentDirectory 所傳回的目前工作目錄為 C:\WINDOWS\system32 資料夾。 System32 資料夾不是儲存服務檔案 (例如,設定檔) 的合適位置。 使用下列其中一個方式來維護及存取服務的資產與設定檔。

使用 ContentRootPath 或 ContentRootFileProvider

使用 IHostEnvironment.ContentRootPathContentRootFileProvider 來找出應用程式的資源。

當應用程式以服務的形式執行時,UseWindowsService 會將 ContentRootPath 設定為 AppContext.BaseDirectory

應用程式的預設設定檔 appsettings.jsonappsettings.{Environment}.json 會藉由在主機建構期間呼叫CreateDefaultBuilder,從應用程式的內容根目錄中載入。

對於 ConfigureAppConfiguration 中開發人員程式碼所載入的其他設定檔,不需要呼叫 SetBasePath。 在下列範例中,custom_settings.json 檔案存在於應用程式的內容根目錄中,而且載入時不會明確設定基本路徑:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("custom_settings.json");
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

請勿嘗試使用 GetCurrentDirectory 來取得資源路徑,因為 Windows 服務應用程式會傳回 C:\WINDOWS\system32 資料夾作為其目前目錄。

將服務的檔案儲存在磁碟上的適當位置

使用包含檔案的 IConfigurationBuilder 資料夾,使用 SetBasePath 來指定絕對路徑。

疑難排解

若要針對 Windows 服務應用程式進行疑難排解,請參閱針對 ASP.NET Core 專案進行疑難排解和偵錯

常見錯誤

  • 正在使用舊版或發行前版本的 PowerShell。
  • 已註冊的服務不會使用來自 dotnet publish 命令的應用程式已發行輸出。 應用程式部署不支援 dotnet build 命令的輸出。 根據部署類型,在下列其中一個資料夾中找到已發行的資產:
    • bin/Release/{TARGET FRAMEWORK}/publish (FDD)
    • bin/Release/{TARGET FRAMEWORK}/{RUNTIME IDENTIFIER}/publish (SCD)
  • 服務未處於「執行中」狀態。
  • 應用程式使用的資源路徑 (例如憑證) 不正確。 Windows 服務的基底路徑為 c:\Windows\System32
  • 使用者沒有以服務方式登入 的權限。
  • 執行 New-Service PowerShell 命令時,使用者的密碼已過期或以不正確的方式傳遞。
  • 應用程式須使用 ASP.NET Core 驗證,但並未針對安全連線 (HTTPS) 設定。
  • 要求 URL 連接埠不正確或未在應用程式中正確設定。

系統和應用程式事件記錄檔

存取系統和應用程式事件記錄檔:

  1. 開啟 [開始] 功能表,搜尋事件檢視器,然後選取 [事件檢視器] 應用程式。
  2. 在 [事件檢視器] 中,開啟 [Windows 記錄] 節點。
  3. 選取 [系統] 以開啟 [系統事件記錄檔]。 選取 [應用程式] 以開啟「應用程式事件記錄檔」。
  4. 搜尋與失敗應用程式相關的錯誤。

在命令提示字元中執行應用程式

許多啟動錯誤不會在事件記錄檔中產生實用的資訊。 您可以藉由在主控系統上的命令提示字元中執行應用程式,來找出一些錯誤的原因。 若要從應用程式記錄其他詳細資料,請降低記錄層級,或在開發環境中執行應用程式。

清除套件快取

在升級開發電腦上的 .NET Core SDK 或變更應用程式內的套件版本之後,正常運作的應用程式便立即發生失敗。 在某些情況下,執行主要升級時,不一致的套件可能會中斷應用程式。 大多數這些問題都可依照下列指示來進行修正:

  1. 刪除 [bin] 和 [obj] 資料夾。

  2. 您可以從命令殼層執行 dotnet nuget locals all --clear 來清除套件快取。

    您也可以使用 nuget.exe 工具並執行 nuget locals all -clear 命令,來清除套件快取。 nuget.exe 並未隨附在 Windows 桌面作業系統的安裝中,必須另外從 NuGet 網站取得。

  3. 還原並重建專案。

  4. 在重新部署應用程式之前,請先刪除伺服器上部署資料夾中的所有檔案。

應用程式緩慢或沒有回應

「損毀傾印」是系統記憶體的快照集,可協助您判斷應用程式損毀、啟動失敗或應用程式緩慢的原因。

應用程式損毀或發生例外狀況

Windows 錯誤報告 (WER) 取得並分析傾印:

  1. c:\dumps 中建立資料夾以保存損毀傾印檔案。

  2. 使用應用程式可執行檔名稱執行 EnableDumps PowerShell 指令碼

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. 在會導致損毀的情況下,執行應用程式。

  4. 發生損毀之後,請執行 DisableDumps PowerShell 指令碼

    .\DisableDumps {APPLICATION EXE}
    

在應用程式損毀且傾印收集完成之後,即可正常結束應用程式。 PowerShell 指令碼會將 WER 設定為每個應用程式收集最多五個傾印。

警告

損毀傾印可能會佔用大量磁碟空間 (每個高達好幾 GB)。

應用程式沒有回應、在啟動期間失敗或正常執行

當應用程式停止回應 (停止回應但不會當機)、在啟動期間失敗或正常執行時,請參閱使用者模式傾印檔案:選擇最佳工具以選取適當的工具來產生傾印。

分析傾印

您可以使用數種方法來分析傾印。 如需詳細資訊,請參閱分析使用者模式傾印檔案

其他資源

ASP.NET Core 應用程式可以裝載在 Windows 上作為 Windows 服務,不需要使用 IIS。 當裝載為 Windows 服務時,應用程式將會在伺服器重新開機後自動啟動。

檢視或下載範例程式碼 \(英文\) (如何下載)

必要條件

背景工作服務範本

ASP.NET Core 背景工作服務範本提供撰寫長期執行服務應用程式的起點。 使用範本作為 Windows 服務應用程式的基礎:

  1. 從 .NET Core 範本建立背景工作服務應用程式。
  2. 請遵循應用程式組態一節中的指導方針,更新背景工作服務應用程式,以便其執行為 Windows 服務。
  1. 建立新專案。
  2. 選取 [背景工作服務]。 選取 [下一步] 。
  3. 在 [專案名稱] 欄位中提供專案名稱,或接受預設專案名稱。 選取建立
  4. 在 [建立新的背景工作服務] 對話方塊中,選取 [建立]。

應用程式設定

應用程式需要 Microsoft.Extensions.Hosting.WindowsServices 的套件參考。

IHostBuilder.UseWindowsService 會在建置主機時呼叫。 如果應用程式以 Windows 服務形式執行,則方法會:

  • 將主機存留期設定為 WindowsServiceLifetime
  • 內容根目錄設定為 AppContext.BaseDirectory。 如需詳細資訊,請參閱目前目錄與內容根目錄一節。
  • 啟用記錄至事件記錄檔功能:
    • 應用程式名稱會作為預設來源名稱。
    • 根據呼叫 CreateDefaultBuilder 以建置主機的 ASP.NET Core 範本,應用程式的預設記錄層級為警告或更新版本。
    • appsettings.json/appsettings.{Environment}.json 或其他組態提供者中,使用 Logging:EventLog:LogLevel:Default 索引鍵覆寫預設記錄層級。
    • 只有系統管理員才能建立新的事件來源。 如果無法使用應用程式名稱建立事件來源,則會向「應用程式」來源記錄警告,並停用事件記錄檔。

Program.csCreateHostBuilder 中:

Host.CreateDefaultBuilder(args)
    .UseWindowsService()
    ...

本主題隨附下列範例應用程式:

  • 背景工作服務範例:以背景工作服務範本為基礎的非 Web 應用程式範例,該範本使用託管服務來執行背景工作。
  • Web 應用程式服務範例:以 Windows 服務形式執行的 Razor Pages Web 應用程式範例,其包含用於背景工作的託管服務

如需 MVC 指引,請參閱 ASP.NET Core MVC 概觀從 ASP.NET Core 2.2 移轉到 3.0 底下的文章。

部署類型

如需詳細資訊與部署案例建議,請參閱 .NET Core 應用程式部署

SDK

對於使用 Razor Pages 或 MVC 架構的 Web 應用程式型服務,請在專案檔中指定 Web SDK:

<Project Sdk="Microsoft.NET.Sdk.Web">

如果服務只執行背景工作 (例如託管服務),請在專案檔中指定背景工作 SDK:

<Project Sdk="Microsoft.NET.Sdk.Worker">

架構相依部署 (FDD)

架構相依部署 (FDD) 仰賴存在於目標系統上的全系統共用 .NET Core 版本。 依照此文章中的指導方針採用 FDD 案例時,SDK 會產生可執行檔 (.exe),稱為「架構相依可執行檔」

如果使用 Web SDK,Windows Services 應用程式不需要 web.config 檔案 (發行 ASP.NET Core 應用程式時通常會產生此檔案)。 若要停用 web.config 檔案的建立,請新增 <IsTransformWebConfigDisabled> 屬性集到 true

<PropertyGroup>
  <TargetFramework>netcoreapp3.0</TargetFramework>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

自封式部署 (SCD)

自封式部署 (SCD) 不仰賴任何存在於主機系統上的共用架構。 執行階段與應用程式的相依性會隨著應用程式進行部署。

Windows 執行階段識別碼 (RID) 會納入包含目標 Framework 的 <PropertyGroup> 中:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

發行多個 RID:

如需詳細資訊,請參閱 .NET Core RID 目錄

服務使用者帳戶

若要為服務建立使用者帳戶,請從系統管理 PowerShell 6 命令殼層使用 New-LocalUser Cmdlet。

Windows 10 2018 年 10 月更新 (版本 1809/組建 10.0.17763) 或更新版本:

New-LocalUser -Name {SERVICE NAME}

在 Windows 10 2018 年 10 月更新之前 (1809 版/組建 10.0.17763) 的 Windows OS 上:

powershell -Command "New-LocalUser -Name {SERVICE NAME}"

在系統提示時提供強式密碼

除非搭配過期 DateTime-AccountExpires 參數提供給 New-LocalUser Cmdlet,否則該帳戶將不會過期。

如需詳細資訊,請參閱 Microsoft.PowerShell.LocalAccounts服務使用者帳戶

使用 Active Directory 時有一個管理使用者的替代方法,就是使用「受控服務帳戶」。 如需詳細資訊,請參閱群組受控服務帳戶概觀

以服務方式登入權限

若要為服務使用者帳戶建立「以服務方式登入」權限:

  1. 執行 secpol.msc 來開啟 [本機安全性原則編輯器]。
  2. 展開 [本機原則] 節點,然後選取 [使用者權限指派]
  3. 開啟 [以服務方式登入] 原則。
  4. 選取 [新增使用者或群組]
  5. 使用下列其中一種方法提供物件名稱 (使用者帳戶):
    1. 在物件名稱欄位中輸入使用者帳戶 ({DOMAIN OR COMPUTER NAME\USER}),然後選取 [確定] 將使用者新增至原則。
    2. 選取進階。 選取 [立即尋找]。 從清單中選取使用者帳戶。 選取 [確定]。 再次選取 [確定] 將使用者新增至原則。
  6. 選取 [確定] 或 [套用] 以接受變更。

建立及管理 Windows 服務

建立服務

使用 PowerShell 命令來註冊服務。 透過系統管理 PowerShell 6 命令殼層,執行下列命令:

$acl = Get-Acl "{EXE PATH}"
$aclRuleArgs = "{DOMAIN OR COMPUTER NAME\USER}", "Read,Write,ReadAndExecute", "ContainerInherit,ObjectInherit", "None", "Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule($aclRuleArgs)
$acl.SetAccessRule($accessRule)
$acl | Set-Acl "{EXE PATH}"

New-Service -Name {SERVICE NAME} -BinaryPathName "{EXE FILE PATH}" -Credential "{DOMAIN OR COMPUTER NAME\USER}" -Description "{DESCRIPTION}" -DisplayName "{DISPLAY NAME}" -StartupType Automatic
  • {EXE PATH}:應用程式可執行檔在主機上的路徑 (例如 d:\myservice)。 請勿在路徑中包含應用程式可執行檔的檔案名稱。 不需要結尾的斜線。
  • {DOMAIN OR COMPUTER NAME\USER}:服務使用者帳戶 (例如 Contoso\ServiceUser)。
  • {SERVICE NAME}:服務名稱 (例如 MyService)。
  • {EXE FILE PATH}:應用程式的完整可執行檔路徑 (例如 d:\myservice\myservice.exe)。 包含可執行檔的檔案名稱 (包含副檔名)。
  • {DESCRIPTION}:服務描述 (例如 My sample service)。
  • {DISPLAY NAME}:服務顯示名稱 (例如 My Service)。

啟動服務

以下列 PowerShell 6 命令啟動服務:

Start-Service -Name {SERVICE NAME}

此命令需要幾秒鐘啓動服務。

判斷服務的狀態

若要檢查服務狀態,請使用下列 PowerShell 6 命令:

Get-Service -Name {SERVICE NAME}

狀態會回報為下列值之一:

  • Starting
  • Running
  • Stopping
  • Stopped

停止服務

使用下列 PowerShell 6 命令停止服務:

Stop-Service -Name {SERVICE NAME}

移除服務

在停止服務的短暫延遲之後,請以下列 PowerShell 6 命令移除服務:

Remove-Service -Name {SERVICE NAME}

Proxy 伺服器和負載平衡器案例

服務如果會與來自網際網路或公司網路的要求進行互動,並且位於 Proxy 或負載平衡器後方,可能會需要額外的設定。 如需詳細資訊,請參閱設定 ASP.NET Core 以處理 Proxy 伺服器和負載平衡器

設定端點

ASP.NET Core 預設會繫結至 http://localhost:5000。 透過設定 ASPNETCORE_URLS 環境變數來設定 URL 和連接埠。

如需其他 URL 和連接埠組態方法,請參閱相關的伺服器文章:

上述指引涵蓋了 HTTPS 端點的支援。 例如,在搭配 Windows 服務使用驗證時,針對 HTTPS 設定應用程式。

注意

不支援使用 ASP.NET Core HTTPS 開發憑證來保護服務端點。

目前目錄和內容根目錄

針對 Windows 服務呼叫 GetCurrentDirectory 所傳回的目前工作目錄為 C:\WINDOWS\system32 資料夾。 System32 資料夾不是儲存服務檔案 (例如,設定檔) 的合適位置。 使用下列其中一個方式來維護及存取服務的資產與設定檔。

使用 ContentRootPath 或 ContentRootFileProvider

使用 IHostEnvironment.ContentRootPathContentRootFileProvider 來找出應用程式的資源。

當應用程式以服務的形式執行時,UseWindowsService 會將 ContentRootPath 設定為 AppContext.BaseDirectory

應用程式的預設設定檔 appsettings.jsonappsettings.{Environment}.json 會藉由在主機建構期間呼叫CreateDefaultBuilder,從應用程式的內容根目錄中載入。

對於 ConfigureAppConfiguration 中開發人員程式碼所載入的其他設定檔,不需要呼叫 SetBasePath。 在下列範例中,custom_settings.json 檔案存在於應用程式的內容根目錄中,而且載入時不會明確設定基本路徑:

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseWindowsService()
            .ConfigureAppConfiguration((hostingContext, config) =>
            {
                config.AddJsonFile("custom_settings.json");
            })
            .ConfigureServices((hostContext, services) =>
            {
                services.AddHostedService<Worker>();
            });
}

請勿嘗試使用 GetCurrentDirectory 來取得資源路徑,因為 Windows 服務應用程式會傳回 C:\WINDOWS\system32 資料夾作為其目前目錄。

將服務的檔案儲存在磁碟上的適當位置

使用包含檔案的 IConfigurationBuilder 資料夾,使用 SetBasePath 來指定絕對路徑。

疑難排解

若要針對 Windows 服務應用程式進行疑難排解,請參閱針對 ASP.NET Core 專案進行疑難排解和偵錯

常見錯誤

  • 正在使用舊版或發行前版本的 PowerShell。
  • 已註冊的服務不會使用來自 dotnet publish 命令的應用程式已發行輸出。 應用程式部署不支援 dotnet build 命令的輸出。 根據部署類型,在下列其中一個資料夾中找到已發行的資產:
    • bin/Release/{TARGET FRAMEWORK}/publish (FDD)
    • bin/Release/{TARGET FRAMEWORK}/{RUNTIME IDENTIFIER}/publish (SCD)
  • 服務未處於「執行中」狀態。
  • 應用程式使用的資源路徑 (例如憑證) 不正確。 Windows 服務的基底路徑為 c:\Windows\System32
  • 使用者沒有以服務方式登入 的權限。
  • 執行 New-Service PowerShell 命令時,使用者的密碼已過期或以不正確的方式傳遞。
  • 應用程式須使用 ASP.NET Core 驗證,但並未針對安全連線 (HTTPS) 設定。
  • 要求 URL 連接埠不正確或未在應用程式中正確設定。

系統和應用程式事件記錄檔

存取系統和應用程式事件記錄檔:

  1. 開啟 [開始] 功能表,搜尋事件檢視器,然後選取 [事件檢視器] 應用程式。
  2. 在 [事件檢視器] 中,開啟 [Windows 記錄] 節點。
  3. 選取 [系統] 以開啟 [系統事件記錄檔]。 選取 [應用程式] 以開啟「應用程式事件記錄檔」。
  4. 搜尋與失敗應用程式相關的錯誤。

在命令提示字元中執行應用程式

許多啟動錯誤不會在事件記錄檔中產生實用的資訊。 您可以藉由在主控系統上的命令提示字元中執行應用程式,來找出一些錯誤的原因。 若要從應用程式記錄其他詳細資料,請降低記錄層級,或在開發環境中執行應用程式。

清除套件快取

在升級開發電腦上的 .NET Core SDK 或變更應用程式內的套件版本之後,正常運作的應用程式便立即發生失敗。 在某些情況下,執行主要升級時,不一致的套件可能會中斷應用程式。 大多數這些問題都可依照下列指示來進行修正:

  1. 刪除 [bin] 和 [obj] 資料夾。

  2. 您可以從命令殼層執行 dotnet nuget locals all --clear 來清除套件快取。

    您也可以使用 nuget.exe 工具並執行 nuget locals all -clear 命令,來清除套件快取。 nuget.exe 並未隨附在 Windows 桌面作業系統的安裝中,必須另外從 NuGet 網站取得。

  3. 還原並重建專案。

  4. 在重新部署應用程式之前,請先刪除伺服器上部署資料夾中的所有檔案。

應用程式緩慢或沒有回應

「損毀傾印」是系統記憶體的快照集,可協助您判斷應用程式損毀、啟動失敗或應用程式緩慢的原因。

應用程式損毀或發生例外狀況

Windows 錯誤報告 (WER) 取得並分析傾印:

  1. c:\dumps 中建立資料夾以保存損毀傾印檔案。

  2. 使用應用程式可執行檔名稱執行 EnableDumps PowerShell 指令碼

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. 在會導致損毀的情況下,執行應用程式。

  4. 發生損毀之後,請執行 DisableDumps PowerShell 指令碼

    .\DisableDumps {APPLICATION EXE}
    

在應用程式損毀且傾印收集完成之後,即可正常結束應用程式。 PowerShell 指令碼會將 WER 設定為每個應用程式收集最多五個傾印。

警告

損毀傾印可能會佔用大量磁碟空間 (每個高達好幾 GB)。

應用程式沒有回應、在啟動期間失敗或正常執行

當應用程式停止回應 (停止回應但不會當機)、在啟動期間失敗或正常執行時,請參閱使用者模式傾印檔案:選擇最佳工具以選取適當的工具來產生傾印。

分析傾印

您可以使用數種方法來分析傾印。 如需詳細資訊,請參閱分析使用者模式傾印檔案

其他資源