在 Windows 服務上裝載 ASP.NET CoreHost ASP.NET Core in a Windows Service

作者:Luke LathamBy Luke Latham

ASP.NET Core 應用程式可以裝載在 Windows 上作為 Windows 服務,不需要使用 IIS。An ASP.NET Core app can be hosted on Windows as a Windows Service without using IIS. 當裝載為 Windows 服務時,應用程式將會在伺服器重新開機後自動啟動。When hosted as a Windows Service, the app automatically starts after server reboots.

檢視或下載範例程式碼 (英文) (如何下載)View or download sample code (how to download)

必要條件Prerequisites

背景工作服務範本Worker Service template

ASP.NET Core 背景工作服務範本提供撰寫長期執行服務應用程式的起點。The ASP.NET Core Worker Service template provides a starting point for writing long running service apps. 使用範本作為 Windows 服務應用程式的基礎:To use the template as a basis for a Windows Service app:

  1. 從 .NET Core 範本建立背景工作服務應用程式。Create a Worker Service app from the .NET Core template.
  2. 請遵循應用程式組態一節中的指導方針,更新背景工作服務應用程式,以便其執行為 Windows 服務。Follow the guidance in the App configuration section to update the Worker Service app so that it can run as a Windows Service.
  1. 建立新的專案。Create a new project.
  2. 選取 [背景工作服務]。Select Worker Service. 選取 [下一步]。Select Next.
  3. 在 [專案名稱] 欄位中提供專案名稱,或接受預設專案名稱。Provide a project name in the Project name field or accept the default project name. 選取 [建立]。Select Create.
  4. 在 [建立新的背景工作服務] 對話方塊中,選取 [建立]。In the Create a new Worker service dialog, select Create.

應用程式設定App configuration

應用程式需要WindowsServices的套件參考。The app requires a package reference for Microsoft.Extensions.Hosting.WindowsServices.

建立主機時,會呼叫 IHostBuilder.UseWindowsServiceIHostBuilder.UseWindowsService is called when building the host. 如果應用程式以 Windows 服務形式執行,則方法會:If the app is running as a Windows Service, the method:

  • 將主機存留期設定為 WindowsServiceLifetimeSets the host lifetime to WindowsServiceLifetime.
  • 內容根目錄設定為AppCoNtext. BaseDirectorySets the content root to AppContext.BaseDirectory. 如需詳細資訊,請參閱目前目錄與內容根目錄一節。For more information, see the Current directory and content root section.
  • 啟用記錄至事件記錄檔:Enables logging to the event log:
    • 應用程式名稱會用來做為預設的來源名稱。The application name is used as the default source name.
    • 根據會呼叫 CreateDefaultBuilder 來建立主機的 ASP.NET Core 範本,應用程式的預設記錄層級為警告或更高。The default log level is Warning or higher for an app based on an ASP.NET Core template that calls CreateDefaultBuilder to build the host.
    • 使用appsettings中的 Logging:EventLog:LogLevel:Default 金鑰覆寫/appsettings 中的預設記錄層級 。 {環境}. json或其他設定提供者。Override the default log level with the Logging:EventLog:LogLevel:Default key in appsettings.json/appsettings.{Environment}.json or other configuration provider.
    • 只有系統管理員才能建立新的事件來源。Only administrators can create new event sources. 如果無法使用應用程式名稱建立事件來源,則會向「應用程式」來源記錄警告,並停用事件記錄檔。When an event source can't be created using the application name, a warning is logged to the Application source and event logs are disabled.

Program.csCreateHostBuilder 中:In CreateHostBuilder of Program.cs:

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

本主題隨附的下列範例應用程式:The following sample apps accompany this topic:

  • 背景工作角色服務範例會根據背景工作使用託管服務工作者服務範本,– 非 web 應用程式範例。Background Worker Service Sample – A non-web app sample based on the Worker Service template that uses hosted services for background tasks.
  • Web App Service 範例 – Razor Pages web 應用程式範例,其以 Windows 服務的形式執行,並具有適用于背景工作的託管服務Web App Service Sample – A Razor Pages web app sample that runs as a Windows Service with hosted services for background tasks.

如需 MVC 指引,請參閱 ASP.NET Core MVC 概觀從 ASP.NET Core 2.2 遷移至 3.0底下的文章。For MVC guidance, see the articles under ASP.NET Core MVC 概觀 and 從 ASP.NET Core 2.2 遷移至 3.0.

部署類型Deployment type

如需詳細資訊與部署案例建議,請參閱 .NET Core 應用程式部署For information and advice on deployment scenarios, see .NET Core application deployment.

SDKSDK

針對使用 Razor Pages 或 MVC 架構的 web 應用程式服務,請在專案檔中指定 Web SDK:For a web app-based service that uses the Razor Pages or MVC frameworks, specify the Web SDK in the project file:

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

如果服務只執行背景工作(例如,託管服務),請在專案檔中指定工作者 SDK:If the service only executes background tasks (for example, hosted services), specify the Worker SDK in the project file:

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

架構相依部署 (FDD)Framework-dependent deployment (FDD)

架構相依部署 (FDD) 仰賴存在於目標系統上的全系統共用 .NET Core 版本。Framework-dependent deployment (FDD) relies on the presence of a shared system-wide version of .NET Core on the target system. 依照此文章中的指導方針採用 FDD 案例時,SDK 會產生可執行檔 ( .exe),稱為「架構相依可執行檔」。When the FDD scenario is adopted following the guidance in this article, the SDK produces an executable (.exe), called a framework-dependent executable.

如果使用WEB SDK,通常是在發佈 ASP.NET Core 應用程式時所產生的 web.config檔案,對於 Windows 服務應用程式而言是不必要的。If using the Web SDK, a web.config file, which is normally produced when publishing an ASP.NET Core app, is unnecessary for a Windows Services app. 若要停用 web.config 檔案的建立,請新增 <IsTransformWebConfigDisabled> 屬性集到 trueTo disable the creation of the web.config file, add the <IsTransformWebConfigDisabled> property set to true.

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

自封式部署 (SCD)Self-contained deployment (SCD)

自封式部署 (SCD) 不仰賴任何存在於主機系統上的共用架構。Self-contained deployment (SCD) doesn't rely on the presence of a shared framework on the host system. 執行階段與應用程式的相依性會隨著應用程式進行部署。The runtime and the app's dependencies are deployed with the app.

Windows 執行階段識別碼 (RID) 會納入包含目標 Framework 的 <PropertyGroup> 中:A Windows Runtime Identifier (RID) is included in the <PropertyGroup> that contains the target framework:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

發行多個 RID:To publish for multiple RIDs:

如需詳細資訊,請參閱 .NET Core RID 目錄For more information, see .NET Core RID Catalog.

服務使用者帳戶Service user account

若要為服務建立使用者帳戶,請從系統管理 PowerShell 6 命令殼層使用 New-LocalUser Cmdlet。To create a user account for a service, use the New-LocalUser cmdlet from an administrative PowerShell 6 command shell.

Windows 10 2018 年 10 月更新 (版本 1809/組建 10.0.17763) 或更新版本:On Windows 10 October 2018 Update (version 1809/build 10.0.17763) or later:

New-LocalUser -Name {SERVICE NAME}

在 Windows 10 2018 年 10 月更新之前 (1809 版/組建 10.0.17763) 的 Windows OS 上:On Windows OS earlier than the Windows 10 October 2018 Update (version 1809/build 10.0.17763):

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

在系統提示時提供強式密碼Provide a strong password when prompted.

除非搭配過期 -AccountExpires 參數提供給 New-LocalUserDateTime Cmdlet,否則該帳戶將不會過期。Unless the -AccountExpires parameter is supplied to the New-LocalUser cmdlet with an expiration DateTime, the account doesn't expire.

如需詳細資訊,請參閱 Microsoft.PowerShell.LocalAccounts服務使用者帳戶For more information, see Microsoft.PowerShell.LocalAccounts and Service User Accounts.

使用 Active Directory 時有一個管理使用者的替代方法,就是使用「受控服務帳戶」。An alternative approach to managing users when using Active Directory is to use Managed Service Accounts. 如需詳細資訊,請參閱群組受控服務帳戶概觀For more information, see Group Managed Service Accounts Overview.

以服務方式登入權限Log on as a service rights

若要為服務使用者帳戶建立「以服務方式登入」權限:To establish Log on as a service rights for a service user account:

  1. 執行 secpol.msc 來開啟 [本機安全性原則編輯器]。Open the Local Security Policy editor by running secpol.msc.
  2. 展開 [本機原則] 節點,然後選取 [使用者權限指派]。Expand the Local Policies node and select User Rights Assignment.
  3. 開啟 [以服務方式登入] 原則。Open the Log on as a service policy.
  4. 選取 [新增使用者或群組]。Select Add User or Group.
  5. 使用下列其中一種方法提供物件名稱 (使用者帳戶):Provide the object name (user account) using either of the following approaches:
    1. 在物件名稱欄位中輸入使用者帳戶 ({DOMAIN OR COMPUTER NAME\USER}),然後選取 [確定] 將使用者新增至原則。Type the user account ({DOMAIN OR COMPUTER NAME\USER}) in the object name field and select OK to add the user to the policy.
    2. 選取 [進階]。Select Advanced. 選取 [立即尋找]。Select Find Now. 從清單中選取使用者帳戶。Select the user account from the list. 選取 [確定]Select OK. 再次選取 [確定] 將使用者新增至原則。Select OK again to add the user to the policy.
  6. 選取 [確定] 或 [套用] 以接受變更。Select OK or Apply to accept the changes.

建立及管理 Windows 服務Create and manage the Windows Service

建立服務Create a service

使用 PowerShell 命令來註冊服務。Use PowerShell commands to register a service. 透過系統管理 PowerShell 6 命令殼層,執行下列命令:From an administrative PowerShell 6 command shell, execute the following commands:

$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)。{EXE PATH} – Path to the app's folder on the host (for example, d:\myservice). 請勿包含路徑中應用程式的可執行檔。Don't include the app's executable in the path. 不需要結尾的斜線。A trailing slash isn't required.
  • {DOMAIN OR COMPUTER NAME\USER} – 服務使用者帳戶(例如,Contoso\ServiceUser)。{DOMAIN OR COMPUTER NAME\USER} – Service user account (for example, Contoso\ServiceUser).
  • {SERVICE NAME} – 服務名稱(例如,MyService)。{SERVICE NAME} – Service name (for example, MyService).
  • {EXE FILE PATH} – 應用程式的可執行檔路徑(例如,d:\myservice\myservice.exe)。{EXE FILE PATH} – The app's executable path (for example, d:\myservice\myservice.exe). 包含可執行檔的檔案名稱 (包含副檔名)。Include the executable's file name with extension.
  • {DESCRIPTION} – 服務描述(例如,My sample service)。{DESCRIPTION} – Service description (for example, My sample service).
  • {DISPLAY NAME} – 服務顯示名稱(例如,My Service)。{DISPLAY NAME} – Service display name (for example, My Service).

啟動服務Start a service

以下列 PowerShell 6 命令啟動服務:Start a service with the following PowerShell 6 command:

Start-Service -Name {SERVICE NAME}

此命令需要幾秒鐘啓動服務。The command takes a few seconds to start the service.

判斷服務的狀態Determine a service's status

若要檢查服務狀態,請使用下列 PowerShell 6 命令:To check the status of a service, use the following PowerShell 6 command:

Get-Service -Name {SERVICE NAME}

狀態會回報為下列值之一:The status is reported as one of the following values:

  • Starting
  • Running
  • Stopping
  • Stopped

停止服務Stop a service

使用下列 Powershell 6 命令停止服務:Stop a service with the following Powershell 6 command:

Stop-Service -Name {SERVICE NAME}

移除服務Remove a service

在停止服務的短暫延遲之後,請以下列 Powershell 6 命令移除服務:After a short delay to stop a service, remove a service with the following Powershell 6 command:

Remove-Service -Name {SERVICE NAME}

Proxy 伺服器和負載平衡器案例Proxy server and load balancer scenarios

服務如果會與來自網際網路或公司網路的要求進行互動,並且位於 Proxy 或負載平衡器後方,可能會需要額外的設定。Services that interact with requests from the Internet or a corporate network and are behind a proxy or load balancer might require additional configuration. 如需詳細資訊,請參閱 設定 ASP.NET Core 以與 Proxy 伺服器和負載平衡器搭配運作For more information, see 設定 ASP.NET Core 以與 Proxy 伺服器和負載平衡器搭配運作.

設定端點Configure endpoints

ASP.NET Core 預設會繫結至 http://localhost:5000By default, ASP.NET Core binds to http://localhost:5000. 設定 ASPNETCORE_URLS 環境變數,以設定 URL 和埠。Configure the URL and port by setting the ASPNETCORE_URLS environment variable.

如需其他 URL 和埠設定方法,請參閱相關的伺服器文章:For additional URL and port configuration approaches, see the relevant server article:

前述指引涵蓋 HTTPS 端點的支援。The preceding guidance covers support for HTTPS endpoints. 例如,當搭配 Windows 服務使用驗證時,請為 HTTPS 設定應用程式。For example, configure the app for HTTPS when authentication is used with a Windows Service.

注意

不支援使用 ASP.NET Core HTTPS 開發憑證來保護服務端點。Use of the ASP.NET Core HTTPS development certificate to secure a service endpoint isn't supported.

目前目錄和內容根目錄Current directory and content root

針對 Windows 服務呼叫 GetCurrentDirectory 所傳回的目前工作目錄為 C:\WINDOWS\system32 資料夾。The current working directory returned by calling GetCurrentDirectory for a Windows Service is the C:\WINDOWS\system32 folder. System32 資料夾不是儲存服務檔案 (例如,設定檔) 的合適位置。The system32 folder isn't a suitable location to store a service's files (for example, settings files). 使用下列其中一個方式來維護及存取服務的資產與設定檔。Use one of the following approaches to maintain and access a service's assets and settings files.

使用 ContentRootPath 或 ContentRootFileProviderUse ContentRootPath or ContentRootFileProvider

使用 IHostEnvironment.ContentRootPathContentRootFileProvider 來找出應用程式的資源。Use IHostEnvironment.ContentRootPath or ContentRootFileProvider to locate an app's resources.

當應用程式以服務的形式執行時,UseWindowsService 會將 ContentRootPath 設定為AppCoNtext. BaseDirectoryWhen the app runs as a service, UseWindowsService sets the ContentRootPath to AppContext.BaseDirectory.

應用程式的預設設定檔案appsettings. jsonappsettings。 {環境}. json會在主機結構期間呼叫 CreateDefaultBuilder,從應用程式的內容根目錄載入。The app's default settings files, appsettings.json and appsettings.{Environment}.json, are loaded from the app's content root by calling CreateDefaultBuilder during host construction.

若為開發人員程式碼在 ConfigureAppConfiguration中載入的其他設定檔案,則不需要呼叫 SetBasePathFor other settings files loaded by developer code in ConfigureAppConfiguration, there's no need to call SetBasePath. 在下列範例中, custom_settings 的 json檔案存在於應用程式的內容根目錄中,並在未明確設定基底路徑的情況下載入:In the following example, the custom_settings.json file exists in the app's content root and is loaded without explicitly setting a base path:

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資料夾做為其目前目錄。Don't attempt to use GetCurrentDirectory to obtain a resource path because a Windows Service app returns the C:\WINDOWS\system32 folder as its current directory.

將服務的檔案儲存在磁碟上的適當位置Store a service's files in a suitable location on disk

使用包含檔案的 SetBasePath 資料夾,使用 IConfigurationBuilder 來指定絕對路徑。Specify an absolute path with SetBasePath when using an IConfigurationBuilder to the folder containing the files.

疑難排解Troubleshoot

若要疑難排解 Windows 服務應用程式,請參閱 疑難排解和調試 ASP.NET Core 專案To troubleshoot a Windows Service app, see 疑難排解和調試 ASP.NET Core 專案.

常見錯誤Common errors

  • 舊版或發行前版本的 PowerShell 已在使用中。An old or pre-release version of PowerShell is in use.
  • 已註冊的服務不會使用來自dotnet publish命令的應用程式已發佈輸出。The registered service doesn't use the app's published output from the dotnet publish command. 應用程式部署不支援dotnet build命令的輸出。Output of the dotnet build command isn't supported for app deployment. 根據部署類型,可以在下列其中一個資料夾中找到已發佈的資產:Published assets are found in either of the following folders depending on the deployment type:
    • bin/Release/{TARGET FRAMEWORK}/publish (FDD)bin/Release/{TARGET FRAMEWORK}/publish (FDD)
    • bin/Release/{TARGET FRAMEWORK}/{RUNTIME IDENTIFIER}/publish (SCD)bin/Release/{TARGET FRAMEWORK}/{RUNTIME IDENTIFIER}/publish (SCD)
  • 服務不是處於執行中狀態。The service isn't in the RUNNING state.
  • 應用程式所使用資源的路徑(例如憑證)不正確。The paths to resources that the app uses (for example, certificates) are incorrect. Windows 服務的基底路徑是c:\windows\System32The base path of a Windows Service is c:\Windows\System32.
  • 使用者不具有 [以服務方式登入] 許可權。The user doesn't have Log on as a service rights.
  • 執行 New-Service PowerShell 命令時,使用者的密碼已過期或傳遞錯誤。The user's password is expired or incorrectly passed when executing the New-Service PowerShell command.
  • 應用程式需要 ASP.NET Core 驗證,但未設定安全連線(HTTPS)。The app requires ASP.NET Core authentication but isn't configured for secure connections (HTTPS).
  • 要求 URL 埠不正確,或未在應用程式中正確設定。The request URL port is incorrect or not configured correctly in the app.

系統和應用程式事件記錄檔System and Application Event Logs

存取系統和應用程式事件記錄檔:Access the System and Application Event Logs:

  1. 開啟 [開始] 功能表,搜尋 [事件檢視器],然後選取 [事件檢視器] 應用程式。Open the Start menu, search for Event Viewer, and select the Event Viewer app.
  2. 在 [事件檢視器] 中,開啟 [Windows 記錄] 節點。In Event Viewer, open the Windows Logs node.
  3. 選取 [系統] 以開啟 [系統] 事件記錄檔。Select System to open the System Event Log. 選取 [應用程式] 以開啟「應用程式事件記錄檔」。Select Application to open the Application Event Log.
  4. 搜尋與失敗應用程式相關的錯誤。Search for errors associated with the failing app.

在命令提示字元中執行應用程式Run the app at a command prompt

許多啟動錯誤不會在事件記錄檔中產生有用的資訊。Many startup errors don't produce useful information in the event logs. 您可以藉由在主控系統上的命令提示字元中執行應用程式,來找出一些錯誤的原因。You can find the cause of some errors by running the app at a command prompt on the hosting system. 若要從應用程式記錄其他詳細資料,請降低記錄層級,或在開發環境中執行應用程式。To log additional detail from the app, lower the log level or run the app in the Development environment.

清除套件快取Clear package caches

升級開發電腦上的 .NET Core SDK 或變更應用程式內的套件版本之後,正常運作的應用程式可能會立即失敗。A functioning app may fail immediately after upgrading either the .NET Core SDK on the development machine or changing package versions within the app. 在某些情況下,執行主要升級時,不一致的套件可能會中斷應用程式。In some cases, incoherent packages may break an app when performing major upgrades. 大多數這些問題都可依照下列指示來進行修正:Most of these issues can be fixed by following these instructions:

  1. 刪除 [bin] 和 [obj] 資料夾。Delete the bin and obj folders.

  2. 從命令 shell 執行dotnet nuget 區域變數 all--clear ,以清除套件快取。Clear the package caches by executing dotnet nuget locals all --clear from a command shell.

    您也可以使用nuget.exe工具來完成清除套件快取,並 nuget locals all -clear執行命令。Clearing package caches can also be accomplished with the nuget.exe tool and executing the command nuget locals all -clear. nuget.exe 並未隨附在 Windows 桌面作業系統的安裝中,必須另外從 NuGet 網站取得。nuget.exe isn't a bundled install with the Windows desktop operating system and must be obtained separately from the NuGet website.

  3. 還原並重建專案。Restore and rebuild the project.

  4. 重新部署應用程式之前,請先刪除伺服器上 [部署] 資料夾中的所有檔案。Delete all of the files in the deployment folder on the server prior to redeploying the app.

回應緩慢或無回應的應用程式Slow or hanging app

傾印是系統記憶體的快照集,有助於判斷應用程式損毀、啟動失敗或應用程式緩慢的原因。A crash dump is a snapshot of the system's memory and can help determine the cause of an app crash, startup failure, or slow app.

應用程式損毀或發生例外狀況App crashes or encounters an exception

Windows 錯誤報告 (WER) 取得並分析傾印:Obtain and analyze a dump from Windows Error Reporting (WER):

  1. c:\dumps 中建立資料夾以保存損毀傾印檔案。Create a folder to hold crash dump files at c:\dumps.

  2. 以應用程式可執行檔名稱執行EnableDumps PowerShell 腳本Run the EnableDumps PowerShell script with the application executable name:

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. 在會導致損毀的情況下,執行應用程式。Run the app under the conditions that cause the crash to occur.

  4. 發生損毀之後,請執行 DisableDumps PowerShell 指令碼After the crash has occurred, run the DisableDumps PowerShell script:

    .\DisableDumps {APPLICATION EXE}
    

在應用程式損毀且傾印收集完成之後,即可正常結束應用程式。After an app crashes and dump collection is complete, the app is allowed to terminate normally. PowerShell 指令碼會將 WER 設定為每個應用程式收集最多五個傾印。The PowerShell script configures WER to collect up to five dumps per app.

警告

損毀傾印可能會佔用大量磁碟空間 (每個高達好幾 GB)。Crash dumps might take up a large amount of disk space (up to several gigabytes each).

應用程式停止回應、在啟動期間失敗,或正常執行App hangs, fails during startup, or runs normally

應用程式當機(停止回應但未損毀)、啟動期間失敗,或正常執行時,請參閱使用者模式傾印檔案:選擇最適合的工具來選取適當的工具以產生傾印。When an app hangs (stops responding but doesn't crash), fails during startup, or runs normally, see User-Mode Dump Files: Choosing the Best Tool to select an appropriate tool to produce the dump.

分析傾印Analyze the dump

您可以使用數種方法來分析傾印。A dump can be analyzed using several approaches. 如需詳細資訊,請參閱分析使用者模式傾印檔案For more information, see Analyzing a User-Mode Dump File.

其他資源Additional resources

ASP.NET Core 應用程式可以裝載在 Windows 上作為 Windows 服務,不需要使用 IIS。An ASP.NET Core app can be hosted on Windows as a Windows Service without using IIS. 當裝載為 Windows 服務時,應用程式將會在伺服器重新開機後自動啟動。When hosted as a Windows Service, the app automatically starts after server reboots.

檢視或下載範例程式碼 (英文) (如何下載)View or download sample code (how to download)

必要條件Prerequisites

應用程式設定App configuration

應用程式需要 Microsoft.AspNetCore.Hosting.WindowsServicesMicrosoft.Extensions.Logging.EventLog 的套件參考。The app requires package references for Microsoft.AspNetCore.Hosting.WindowsServices and Microsoft.Extensions.Logging.EventLog.

若要在於服務外執行時測試及偵錯,請新增程式碼以判斷應用程式是以服務形式執行或以主控台應用程式形式執行。To test and debug when running outside of a service, add code to determine if the app is running as a service or a console app. 檢查偵錯工具是否已附加或 --console 切換參數是否存在。Inspect if the debugger is attached or a --console switch is present. 若任一條件為真 (應用程式不是以服務形式執行),請呼叫 RunIf either condition is true (the app isn't run as a service), call Run. 若條件為偽 (應用程式是以服務形式執行):If the conditions are false (the app is run as a service):

因為命令列設定提供者需要命令列引數的名稱值組,在 --console 收到引數之前,CreateDefaultBuilder 切換參數就會從引數中移除。Because the Command-line Configuration Provider requires name-value pairs for command-line arguments, the --console switch is removed from the arguments before CreateDefaultBuilder receives the arguments.

若要寫入 Windows 事件記錄檔,請新增 EventLog 提供者到 ConfigureLoggingTo write to the Windows Event Log, add the EventLog provider to ConfigureLogging. 使用 Logging:LogLevel:Defaultappsettings.Production.json檔案中的 機碼設定記錄層級。Set the logging level with the Logging:LogLevel:Default key in the appsettings.Production.json file.

在範例應用程式的下列範例中,為了處理應用程式內的存留期事件,會呼叫 RunAsCustomService 而不是 RunAsServiceIn the following example from the sample app, RunAsCustomService is called instead of RunAsService in order to handle lifetime events within the app. 如需詳細資訊,請參閱處理開始與停止事件一節。For more information, see the Handle starting and stopping events section.

public class Program
{
    public static void Main(string[] args)
    {
        var isService = !(Debugger.IsAttached || args.Contains("--console"));
        
        if (isService)
        {
            var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
            var pathToContentRoot = Path.GetDirectoryName(pathToExe);
            Directory.SetCurrentDirectory(pathToContentRoot);
        }

        var builder = CreateWebHostBuilder(
            args.Where(arg => arg != "--console").ToArray());

        var host = builder.Build();

        if (isService)
        {
            // To run the app without the CustomWebHostService change the
            // next line to host.RunAsService();
            host.RunAsCustomService();
        }
        else
        {
            host.Run();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddEventLog();
            })
            .ConfigureAppConfiguration((context, config) =>
            {
                // Configure the app here.
            })
            .UseStartup<Startup>();
}

部署類型Deployment type

如需詳細資訊與部署案例建議,請參閱 .NET Core 應用程式部署For information and advice on deployment scenarios, see .NET Core application deployment.

SDKSDK

針對使用 Razor Pages 或 MVC 架構的 web 應用程式服務,請在專案檔中指定 Web SDK:For a web app-based service that uses the Razor Pages or MVC frameworks, specify the Web SDK in the project file:

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

如果服務只執行背景工作(例如,託管服務),請在專案檔中指定工作者 SDK:If the service only executes background tasks (for example, hosted services), specify the Worker SDK in the project file:

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

架構相依部署 (FDD)Framework-dependent deployment (FDD)

架構相依部署 (FDD) 仰賴存在於目標系統上的全系統共用 .NET Core 版本。Framework-dependent deployment (FDD) relies on the presence of a shared system-wide version of .NET Core on the target system. 依照此文章中的指導方針採用 FDD 案例時,SDK 會產生可執行檔 ( .exe),稱為「架構相依可執行檔」。When the FDD scenario is adopted following the guidance in this article, the SDK produces an executable (.exe), called a framework-dependent executable.

Windows 執行階段識別碼 (RID) (<RuntimeIdentifier>) 包含目標 Framework。The Windows Runtime Identifier (RID) (<RuntimeIdentifier>) contains the target framework. 在下列範例中,RID 已設定為 win7-x64In the following example, the RID is set to win7-x64. <SelfContained> 屬性設定為 falseThe <SelfContained> property is set to false. 這些屬性會指示 SDK,針對 Windows 和相依於共用 .NET Core framework 的應用程式產生可執行檔 ( .exe)。These properties instruct the SDK to generate an executable (.exe) file for Windows and an app that depends on the shared .NET Core framework.

針對 Windows Services 應用程式,不需要 web.config 檔案 (發行 ASP.NET Core 應用程式時通常會產生此檔案)。A web.config file, which is normally produced when publishing an ASP.NET Core app, is unnecessary for a Windows Services app. 若要停用 web.config 檔案的建立,請新增 <IsTransformWebConfigDisabled> 屬性集到 trueTo disable the creation of the web.config file, add the <IsTransformWebConfigDisabled> property set to true.

<PropertyGroup>
  <TargetFramework>netcoreapp2.2</TargetFramework>
  <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
  <SelfContained>false</SelfContained>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

自封式部署 (SCD)Self-contained deployment (SCD)

自封式部署 (SCD) 不仰賴任何存在於主機系統上的共用架構。Self-contained deployment (SCD) doesn't rely on the presence of a shared framework on the host system. 執行階段與應用程式的相依性會隨著應用程式進行部署。The runtime and the app's dependencies are deployed with the app.

Windows 執行階段識別碼 (RID) 會納入包含目標 Framework 的 <PropertyGroup> 中:A Windows Runtime Identifier (RID) is included in the <PropertyGroup> that contains the target framework:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

發行多個 RID:To publish for multiple RIDs:

如需詳細資訊,請參閱 .NET Core RID 目錄For more information, see .NET Core RID Catalog.

<SelfContained> 屬性設定為 trueA <SelfContained> property is set to true:

<SelfContained>true</SelfContained>

服務使用者帳戶Service user account

若要為服務建立使用者帳戶,請從系統管理 PowerShell 6 命令殼層使用 New-LocalUser Cmdlet。To create a user account for a service, use the New-LocalUser cmdlet from an administrative PowerShell 6 command shell.

Windows 10 2018 年 10 月更新 (版本 1809/組建 10.0.17763) 或更新版本:On Windows 10 October 2018 Update (version 1809/build 10.0.17763) or later:

New-LocalUser -Name {SERVICE NAME}

在 Windows 10 2018 年 10 月更新之前 (1809 版/組建 10.0.17763) 的 Windows OS 上:On Windows OS earlier than the Windows 10 October 2018 Update (version 1809/build 10.0.17763):

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

在系統提示時提供強式密碼Provide a strong password when prompted.

除非搭配過期 -AccountExpires 參數提供給 New-LocalUserDateTime Cmdlet,否則該帳戶將不會過期。Unless the -AccountExpires parameter is supplied to the New-LocalUser cmdlet with an expiration DateTime, the account doesn't expire.

如需詳細資訊,請參閱 Microsoft.PowerShell.LocalAccounts服務使用者帳戶For more information, see Microsoft.PowerShell.LocalAccounts and Service User Accounts.

使用 Active Directory 時有一個管理使用者的替代方法,就是使用「受控服務帳戶」。An alternative approach to managing users when using Active Directory is to use Managed Service Accounts. 如需詳細資訊,請參閱群組受控服務帳戶概觀For more information, see Group Managed Service Accounts Overview.

以服務方式登入權限Log on as a service rights

若要為服務使用者帳戶建立「以服務方式登入」權限:To establish Log on as a service rights for a service user account:

  1. 執行 secpol.msc 來開啟 [本機安全性原則編輯器]。Open the Local Security Policy editor by running secpol.msc.
  2. 展開 [本機原則] 節點,然後選取 [使用者權限指派]。Expand the Local Policies node and select User Rights Assignment.
  3. 開啟 [以服務方式登入] 原則。Open the Log on as a service policy.
  4. 選取 [新增使用者或群組]。Select Add User or Group.
  5. 使用下列其中一種方法提供物件名稱 (使用者帳戶):Provide the object name (user account) using either of the following approaches:
    1. 在物件名稱欄位中輸入使用者帳戶 ({DOMAIN OR COMPUTER NAME\USER}),然後選取 [確定] 將使用者新增至原則。Type the user account ({DOMAIN OR COMPUTER NAME\USER}) in the object name field and select OK to add the user to the policy.
    2. 選取 [進階]。Select Advanced. 選取 [立即尋找]。Select Find Now. 從清單中選取使用者帳戶。Select the user account from the list. 選取 [確定]Select OK. 再次選取 [確定] 將使用者新增至原則。Select OK again to add the user to the policy.
  6. 選取 [確定] 或 [套用] 以接受變更。Select OK or Apply to accept the changes.

建立及管理 Windows 服務Create and manage the Windows Service

建立服務Create a service

使用 PowerShell 命令來註冊服務。Use PowerShell commands to register a service. 透過系統管理 PowerShell 6 命令殼層,執行下列命令:From an administrative PowerShell 6 command shell, execute the following commands:

$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)。{EXE PATH} – Path to the app's folder on the host (for example, d:\myservice). 請勿包含路徑中應用程式的可執行檔。Don't include the app's executable in the path. 不需要結尾的斜線。A trailing slash isn't required.
  • {DOMAIN OR COMPUTER NAME\USER} – 服務使用者帳戶(例如,Contoso\ServiceUser)。{DOMAIN OR COMPUTER NAME\USER} – Service user account (for example, Contoso\ServiceUser).
  • {SERVICE NAME} – 服務名稱(例如,MyService)。{SERVICE NAME} – Service name (for example, MyService).
  • {EXE FILE PATH} – 應用程式的可執行檔路徑(例如,d:\myservice\myservice.exe)。{EXE FILE PATH} – The app's executable path (for example, d:\myservice\myservice.exe). 包含可執行檔的檔案名稱 (包含副檔名)。Include the executable's file name with extension.
  • {DESCRIPTION} – 服務描述(例如,My sample service)。{DESCRIPTION} – Service description (for example, My sample service).
  • {DISPLAY NAME} – 服務顯示名稱(例如,My Service)。{DISPLAY NAME} – Service display name (for example, My Service).

啟動服務Start a service

以下列 PowerShell 6 命令啟動服務:Start a service with the following PowerShell 6 command:

Start-Service -Name {SERVICE NAME}

此命令需要幾秒鐘啓動服務。The command takes a few seconds to start the service.

判斷服務的狀態Determine a service's status

若要檢查服務狀態,請使用下列 PowerShell 6 命令:To check the status of a service, use the following PowerShell 6 command:

Get-Service -Name {SERVICE NAME}

狀態會回報為下列值之一:The status is reported as one of the following values:

  • Starting
  • Running
  • Stopping
  • Stopped

停止服務Stop a service

使用下列 Powershell 6 命令停止服務:Stop a service with the following Powershell 6 command:

Stop-Service -Name {SERVICE NAME}

移除服務Remove a service

在停止服務的短暫延遲之後,請以下列 Powershell 6 命令移除服務:After a short delay to stop a service, remove a service with the following Powershell 6 command:

Remove-Service -Name {SERVICE NAME}

處理開始與停止事件Handle starting and stopping events

若要處理 OnStartingOnStartedOnStopping 事件:To handle OnStarting, OnStarted, and OnStopping events:

  1. 使用 WebHostServiceOnStartingOnStarted 方法建立衍生自 OnStopping 的類別:Create a class that derives from WebHostService with the OnStarting, OnStarted, and OnStopping methods:

    [DesignerCategory("Code")]
    internal class CustomWebHostService : WebHostService
    {
        private ILogger _logger;
    
        public CustomWebHostService(IWebHost host) : base(host)
        {
            _logger = host.Services
                .GetRequiredService<ILogger<CustomWebHostService>>();
        }
    
        protected override void OnStarting(string[] args)
        {
            _logger.LogInformation("OnStarting method called.");
            base.OnStarting(args);
        }
    
        protected override void OnStarted()
        {
            _logger.LogInformation("OnStarted method called.");
            base.OnStarted();
        }
    
        protected override void OnStopping()
        {
            _logger.LogInformation("OnStopping method called.");
            base.OnStopping();
        }
    }
    
  2. IWebHost 建立一個會將 CustomWebHostService 傳遞給 Run 的擴充方法:Create an extension method for IWebHost that passes the CustomWebHostService to Run:

    public static class WebHostServiceExtensions
    {
        public static void RunAsCustomService(this IWebHost host)
        {
            var webHostService = new CustomWebHostService(host);
            ServiceBase.Run(webHostService);
        }
    }
    
  3. Program.Main 中,呼叫 RunAsCustomService 擴充方法,而不是呼叫 RunAsServiceIn Program.Main, call the RunAsCustomService extension method instead of RunAsService:

    host.RunAsCustomService();
    

    若要查看 RunAsService 中的 Program.Main 位置,請參閱部署類型一節中的範例程式碼。To see the location of RunAsService in Program.Main, refer to the code sample shown in the Deployment type section.

Proxy 伺服器和負載平衡器案例Proxy server and load balancer scenarios

服務如果會與來自網際網路或公司網路的要求進行互動,並且位於 Proxy 或負載平衡器後方,可能會需要額外的設定。Services that interact with requests from the Internet or a corporate network and are behind a proxy or load balancer might require additional configuration. 如需詳細資訊,請參閱 設定 ASP.NET Core 以與 Proxy 伺服器和負載平衡器搭配運作For more information, see 設定 ASP.NET Core 以與 Proxy 伺服器和負載平衡器搭配運作.

設定端點Configure endpoints

ASP.NET Core 預設會繫結至 http://localhost:5000By default, ASP.NET Core binds to http://localhost:5000. 設定 ASPNETCORE_URLS 環境變數,以設定 URL 和埠。Configure the URL and port by setting the ASPNETCORE_URLS environment variable.

如需其他 URL 和埠設定方法,請參閱相關的伺服器文章:For additional URL and port configuration approaches, see the relevant server article:

前述指引涵蓋 HTTPS 端點的支援。The preceding guidance covers support for HTTPS endpoints. 例如,當搭配 Windows 服務使用驗證時,請為 HTTPS 設定應用程式。For example, configure the app for HTTPS when authentication is used with a Windows Service.

注意

不支援使用 ASP.NET Core HTTPS 開發憑證來保護服務端點。Use of the ASP.NET Core HTTPS development certificate to secure a service endpoint isn't supported.

目前目錄和內容根目錄Current directory and content root

針對 Windows 服務呼叫 GetCurrentDirectory 所傳回的目前工作目錄為 C:\WINDOWS\system32 資料夾。The current working directory returned by calling GetCurrentDirectory for a Windows Service is the C:\WINDOWS\system32 folder. System32 資料夾不是儲存服務檔案 (例如,設定檔) 的合適位置。The system32 folder isn't a suitable location to store a service's files (for example, settings files). 使用下列其中一個方式來維護及存取服務的資產與設定檔。Use one of the following approaches to maintain and access a service's assets and settings files.

將內容根目錄路徑設定到應用程式的資料夾Set the content root path to the app's folder

ContentRootPath 與建立服務時提供給 binPath 引數的路徑相同。The ContentRootPath is the same path provided to the binPath argument when a service is created. 請呼叫具有應用程式內容根目錄路徑的 SetCurrentDirectory,而不是呼叫 GetCurrentDirectory 建立設定檔的路徑。Instead of calling GetCurrentDirectory to create paths to settings files, call SetCurrentDirectory with the path to the app's content root.

Program.Main 中,判斷服務可執行檔資料夾的路徑,然後使用該路徑來建立應用程式的內容根目錄:In Program.Main, determine the path to the folder of the service's executable and use the path to establish the app's content root:

var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
var pathToContentRoot = Path.GetDirectoryName(pathToExe);
Directory.SetCurrentDirectory(pathToContentRoot);

CreateWebHostBuilder(args)
    .Build()
    .RunAsService();

將服務的檔案儲存在磁碟上的適當位置Store a service's files in a suitable location on disk

使用包含檔案的 SetBasePath 資料夾,使用 IConfigurationBuilder 來指定絕對路徑。Specify an absolute path with SetBasePath when using an IConfigurationBuilder to the folder containing the files.

疑難排解Troubleshoot

若要疑難排解 Windows 服務應用程式,請參閱 疑難排解和調試 ASP.NET Core 專案To troubleshoot a Windows Service app, see 疑難排解和調試 ASP.NET Core 專案.

常見錯誤Common errors

  • 舊版或發行前版本的 PowerShell 已在使用中。An old or pre-release version of PowerShell is in use.
  • 已註冊的服務不會使用來自dotnet publish命令的應用程式已發佈輸出。The registered service doesn't use the app's published output from the dotnet publish command. 應用程式部署不支援dotnet build命令的輸出。Output of the dotnet build command isn't supported for app deployment. 根據部署類型,可以在下列其中一個資料夾中找到已發佈的資產:Published assets are found in either of the following folders depending on the deployment type:
    • bin/Release/{TARGET FRAMEWORK}/publish (FDD)bin/Release/{TARGET FRAMEWORK}/publish (FDD)
    • bin/Release/{TARGET FRAMEWORK}/{RUNTIME IDENTIFIER}/publish (SCD)bin/Release/{TARGET FRAMEWORK}/{RUNTIME IDENTIFIER}/publish (SCD)
  • 服務不是處於執行中狀態。The service isn't in the RUNNING state.
  • 應用程式所使用資源的路徑(例如憑證)不正確。The paths to resources that the app uses (for example, certificates) are incorrect. Windows 服務的基底路徑是c:\windows\System32The base path of a Windows Service is c:\Windows\System32.
  • 使用者不具有 [以服務方式登入] 許可權。The user doesn't have Log on as a service rights.
  • 執行 New-Service PowerShell 命令時,使用者的密碼已過期或傳遞錯誤。The user's password is expired or incorrectly passed when executing the New-Service PowerShell command.
  • 應用程式需要 ASP.NET Core 驗證,但未設定安全連線(HTTPS)。The app requires ASP.NET Core authentication but isn't configured for secure connections (HTTPS).
  • 要求 URL 埠不正確,或未在應用程式中正確設定。The request URL port is incorrect or not configured correctly in the app.

系統和應用程式事件記錄檔System and Application Event Logs

存取系統和應用程式事件記錄檔:Access the System and Application Event Logs:

  1. 開啟 [開始] 功能表,搜尋 [事件檢視器],然後選取 [事件檢視器] 應用程式。Open the Start menu, search for Event Viewer, and select the Event Viewer app.
  2. 在 [事件檢視器] 中,開啟 [Windows 記錄] 節點。In Event Viewer, open the Windows Logs node.
  3. 選取 [系統] 以開啟 [系統] 事件記錄檔。Select System to open the System Event Log. 選取 [應用程式] 以開啟「應用程式事件記錄檔」。Select Application to open the Application Event Log.
  4. 搜尋與失敗應用程式相關的錯誤。Search for errors associated with the failing app.

在命令提示字元中執行應用程式Run the app at a command prompt

許多啟動錯誤不會在事件記錄檔中產生有用的資訊。Many startup errors don't produce useful information in the event logs. 您可以藉由在主控系統上的命令提示字元中執行應用程式,來找出一些錯誤的原因。You can find the cause of some errors by running the app at a command prompt on the hosting system. 若要從應用程式記錄其他詳細資料,請降低記錄層級,或在開發環境中執行應用程式。To log additional detail from the app, lower the log level or run the app in the Development environment.

清除套件快取Clear package caches

升級開發電腦上的 .NET Core SDK 或變更應用程式內的套件版本之後,正常運作的應用程式可能會立即失敗。A functioning app may fail immediately after upgrading either the .NET Core SDK on the development machine or changing package versions within the app. 在某些情況下,執行主要升級時,不一致的套件可能會中斷應用程式。In some cases, incoherent packages may break an app when performing major upgrades. 大多數這些問題都可依照下列指示來進行修正:Most of these issues can be fixed by following these instructions:

  1. 刪除 [bin] 和 [obj] 資料夾。Delete the bin and obj folders.

  2. 從命令 shell 執行dotnet nuget 區域變數 all--clear ,以清除套件快取。Clear the package caches by executing dotnet nuget locals all --clear from a command shell.

    您也可以使用nuget.exe工具來完成清除套件快取,並 nuget locals all -clear執行命令。Clearing package caches can also be accomplished with the nuget.exe tool and executing the command nuget locals all -clear. nuget.exe 並未隨附在 Windows 桌面作業系統的安裝中,必須另外從 NuGet 網站取得。nuget.exe isn't a bundled install with the Windows desktop operating system and must be obtained separately from the NuGet website.

  3. 還原並重建專案。Restore and rebuild the project.

  4. 重新部署應用程式之前,請先刪除伺服器上 [部署] 資料夾中的所有檔案。Delete all of the files in the deployment folder on the server prior to redeploying the app.

回應緩慢或無回應的應用程式Slow or hanging app

傾印是系統記憶體的快照集,有助於判斷應用程式損毀、啟動失敗或應用程式緩慢的原因。A crash dump is a snapshot of the system's memory and can help determine the cause of an app crash, startup failure, or slow app.

應用程式損毀或發生例外狀況App crashes or encounters an exception

Windows 錯誤報告 (WER) 取得並分析傾印:Obtain and analyze a dump from Windows Error Reporting (WER):

  1. c:\dumps 中建立資料夾以保存損毀傾印檔案。Create a folder to hold crash dump files at c:\dumps.

  2. 以應用程式可執行檔名稱執行EnableDumps PowerShell 腳本Run the EnableDumps PowerShell script with the application executable name:

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. 在會導致損毀的情況下,執行應用程式。Run the app under the conditions that cause the crash to occur.

  4. 發生損毀之後,請執行 DisableDumps PowerShell 指令碼After the crash has occurred, run the DisableDumps PowerShell script:

    .\DisableDumps {APPLICATION EXE}
    

在應用程式損毀且傾印收集完成之後,即可正常結束應用程式。After an app crashes and dump collection is complete, the app is allowed to terminate normally. PowerShell 指令碼會將 WER 設定為每個應用程式收集最多五個傾印。The PowerShell script configures WER to collect up to five dumps per app.

警告

損毀傾印可能會佔用大量磁碟空間 (每個高達好幾 GB)。Crash dumps might take up a large amount of disk space (up to several gigabytes each).

應用程式停止回應、在啟動期間失敗,或正常執行App hangs, fails during startup, or runs normally

應用程式當機(停止回應但未損毀)、啟動期間失敗,或正常執行時,請參閱使用者模式傾印檔案:選擇最適合的工具來選取適當的工具以產生傾印。When an app hangs (stops responding but doesn't crash), fails during startup, or runs normally, see User-Mode Dump Files: Choosing the Best Tool to select an appropriate tool to produce the dump.

分析傾印Analyze the dump

您可以使用數種方法來分析傾印。A dump can be analyzed using several approaches. 如需詳細資訊,請參閱分析使用者模式傾印檔案For more information, see Analyzing a User-Mode Dump File.

其他資源Additional resources

ASP.NET Core 應用程式可以裝載在 Windows 上作為 Windows 服務,不需要使用 IIS。An ASP.NET Core app can be hosted on Windows as a Windows Service without using IIS. 當裝載為 Windows 服務時,應用程式將會在伺服器重新開機後自動啟動。When hosted as a Windows Service, the app automatically starts after server reboots.

檢視或下載範例程式碼 (英文) (如何下載)View or download sample code (how to download)

必要條件Prerequisites

應用程式設定App configuration

應用程式需要 Microsoft.AspNetCore.Hosting.WindowsServicesMicrosoft.Extensions.Logging.EventLog 的套件參考。The app requires package references for Microsoft.AspNetCore.Hosting.WindowsServices and Microsoft.Extensions.Logging.EventLog.

若要在於服務外執行時測試及偵錯,請新增程式碼以判斷應用程式是以服務形式執行或以主控台應用程式形式執行。To test and debug when running outside of a service, add code to determine if the app is running as a service or a console app. 檢查偵錯工具是否已附加或 --console 切換參數是否存在。Inspect if the debugger is attached or a --console switch is present. 若任一條件為真 (應用程式不是以服務形式執行),請呼叫 RunIf either condition is true (the app isn't run as a service), call Run. 若條件為偽 (應用程式是以服務形式執行):If the conditions are false (the app is run as a service):

因為命令列設定提供者需要命令列引數的名稱值組,在 --console 收到引數之前,CreateDefaultBuilder 切換參數就會從引數中移除。Because the Command-line Configuration Provider requires name-value pairs for command-line arguments, the --console switch is removed from the arguments before CreateDefaultBuilder receives the arguments.

若要寫入 Windows 事件記錄檔,請新增 EventLog 提供者到 ConfigureLoggingTo write to the Windows Event Log, add the EventLog provider to ConfigureLogging. 使用 Logging:LogLevel:Defaultappsettings.Production.json檔案中的 機碼設定記錄層級。Set the logging level with the Logging:LogLevel:Default key in the appsettings.Production.json file.

在範例應用程式的下列範例中,為了處理應用程式內的存留期事件,會呼叫 RunAsCustomService 而不是 RunAsServiceIn the following example from the sample app, RunAsCustomService is called instead of RunAsService in order to handle lifetime events within the app. 如需詳細資訊,請參閱處理開始與停止事件一節。For more information, see the Handle starting and stopping events section.

public class Program
{
    public static void Main(string[] args)
    {
        var isService = !(Debugger.IsAttached || args.Contains("--console"));
        
        if (isService)
        {
            var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
            var pathToContentRoot = Path.GetDirectoryName(pathToExe);
            Directory.SetCurrentDirectory(pathToContentRoot);
        }

        var builder = CreateWebHostBuilder(
            args.Where(arg => arg != "--console").ToArray());

        var host = builder.Build();

        if (isService)
        {
            // To run the app without the CustomWebHostService change the
            // next line to host.RunAsService();
            host.RunAsCustomService();
        }
        else
        {
            host.Run();
        }
    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .ConfigureLogging((hostingContext, logging) =>
            {
                logging.AddEventLog();
            })
            .ConfigureAppConfiguration((context, config) =>
            {
                // Configure the app here.
            })
            .UseStartup<Startup>();
}

部署類型Deployment type

如需詳細資訊與部署案例建議,請參閱 .NET Core 應用程式部署For information and advice on deployment scenarios, see .NET Core application deployment.

SDKSDK

針對使用 Razor Pages 或 MVC 架構的 web 應用程式服務,請在專案檔中指定 Web SDK:For a web app-based service that uses the Razor Pages or MVC frameworks, specify the Web SDK in the project file:

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

如果服務只執行背景工作(例如,託管服務),請在專案檔中指定工作者 SDK:If the service only executes background tasks (for example, hosted services), specify the Worker SDK in the project file:

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

架構相依部署 (FDD)Framework-dependent deployment (FDD)

架構相依部署 (FDD) 仰賴存在於目標系統上的全系統共用 .NET Core 版本。Framework-dependent deployment (FDD) relies on the presence of a shared system-wide version of .NET Core on the target system. 依照此文章中的指導方針採用 FDD 案例時,SDK 會產生可執行檔 ( .exe),稱為「架構相依可執行檔」。When the FDD scenario is adopted following the guidance in this article, the SDK produces an executable (.exe), called a framework-dependent executable.

Windows 執行階段識別碼 (RID) (<RuntimeIdentifier>) 包含目標 Framework。The Windows Runtime Identifier (RID) (<RuntimeIdentifier>) contains the target framework. 在下列範例中,RID 已設定為 win7-x64In the following example, the RID is set to win7-x64. <SelfContained> 屬性設定為 falseThe <SelfContained> property is set to false. 這些屬性會指示 SDK,針對 Windows 和相依於共用 .NET Core framework 的應用程式產生可執行檔 ( .exe)。These properties instruct the SDK to generate an executable (.exe) file for Windows and an app that depends on the shared .NET Core framework.

<UseAppHost> 屬性設定為 trueThe <UseAppHost> property is set to true. 此屬性為服務提供 FDD 的啟用路徑 (可執行檔 .exe)。This property provides the service with an activation path (an executable, .exe) for an FDD.

針對 Windows Services 應用程式,不需要 web.config 檔案 (發行 ASP.NET Core 應用程式時通常會產生此檔案)。A web.config file, which is normally produced when publishing an ASP.NET Core app, is unnecessary for a Windows Services app. 若要停用 web.config 檔案的建立,請新增 <IsTransformWebConfigDisabled> 屬性集到 trueTo disable the creation of the web.config file, add the <IsTransformWebConfigDisabled> property set to true.

<PropertyGroup>
  <TargetFramework>netcoreapp2.2</TargetFramework>
  <RuntimeIdentifier>win7-x64</RuntimeIdentifier>
  <UseAppHost>true</UseAppHost>
  <SelfContained>false</SelfContained>
  <IsTransformWebConfigDisabled>true</IsTransformWebConfigDisabled>
</PropertyGroup>

自封式部署 (SCD)Self-contained deployment (SCD)

自封式部署 (SCD) 不仰賴任何存在於主機系統上的共用架構。Self-contained deployment (SCD) doesn't rely on the presence of a shared framework on the host system. 執行階段與應用程式的相依性會隨著應用程式進行部署。The runtime and the app's dependencies are deployed with the app.

Windows 執行階段識別碼 (RID) 會納入包含目標 Framework 的 <PropertyGroup> 中:A Windows Runtime Identifier (RID) is included in the <PropertyGroup> that contains the target framework:

<RuntimeIdentifier>win7-x64</RuntimeIdentifier>

發行多個 RID:To publish for multiple RIDs:

如需詳細資訊,請參閱 .NET Core RID 目錄For more information, see .NET Core RID Catalog.

<SelfContained> 屬性設定為 trueA <SelfContained> property is set to true:

<SelfContained>true</SelfContained>

服務使用者帳戶Service user account

若要為服務建立使用者帳戶,請從系統管理 PowerShell 6 命令殼層使用 New-LocalUser Cmdlet。To create a user account for a service, use the New-LocalUser cmdlet from an administrative PowerShell 6 command shell.

Windows 10 2018 年 10 月更新 (版本 1809/組建 10.0.17763) 或更新版本:On Windows 10 October 2018 Update (version 1809/build 10.0.17763) or later:

New-LocalUser -Name {SERVICE NAME}

在 Windows 10 2018 年 10 月更新之前 (1809 版/組建 10.0.17763) 的 Windows OS 上:On Windows OS earlier than the Windows 10 October 2018 Update (version 1809/build 10.0.17763):

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

在系統提示時提供強式密碼Provide a strong password when prompted.

除非搭配過期 -AccountExpires 參數提供給 New-LocalUserDateTime Cmdlet,否則該帳戶將不會過期。Unless the -AccountExpires parameter is supplied to the New-LocalUser cmdlet with an expiration DateTime, the account doesn't expire.

如需詳細資訊,請參閱 Microsoft.PowerShell.LocalAccounts服務使用者帳戶For more information, see Microsoft.PowerShell.LocalAccounts and Service User Accounts.

使用 Active Directory 時有一個管理使用者的替代方法,就是使用「受控服務帳戶」。An alternative approach to managing users when using Active Directory is to use Managed Service Accounts. 如需詳細資訊,請參閱群組受控服務帳戶概觀For more information, see Group Managed Service Accounts Overview.

以服務方式登入權限Log on as a service rights

若要為服務使用者帳戶建立「以服務方式登入」權限:To establish Log on as a service rights for a service user account:

  1. 執行 secpol.msc 來開啟 [本機安全性原則編輯器]。Open the Local Security Policy editor by running secpol.msc.
  2. 展開 [本機原則] 節點,然後選取 [使用者權限指派]。Expand the Local Policies node and select User Rights Assignment.
  3. 開啟 [以服務方式登入] 原則。Open the Log on as a service policy.
  4. 選取 [新增使用者或群組]。Select Add User or Group.
  5. 使用下列其中一種方法提供物件名稱 (使用者帳戶):Provide the object name (user account) using either of the following approaches:
    1. 在物件名稱欄位中輸入使用者帳戶 ({DOMAIN OR COMPUTER NAME\USER}),然後選取 [確定] 將使用者新增至原則。Type the user account ({DOMAIN OR COMPUTER NAME\USER}) in the object name field and select OK to add the user to the policy.
    2. 選取 [進階]。Select Advanced. 選取 [立即尋找]。Select Find Now. 從清單中選取使用者帳戶。Select the user account from the list. 選取 [確定]Select OK. 再次選取 [確定] 將使用者新增至原則。Select OK again to add the user to the policy.
  6. 選取 [確定] 或 [套用] 以接受變更。Select OK or Apply to accept the changes.

建立及管理 Windows 服務Create and manage the Windows Service

建立服務Create a service

使用 PowerShell 命令來註冊服務。Use PowerShell commands to register a service. 透過系統管理 PowerShell 6 命令殼層,執行下列命令:From an administrative PowerShell 6 command shell, execute the following commands:

$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)。{EXE PATH} – Path to the app's folder on the host (for example, d:\myservice). 請勿包含路徑中應用程式的可執行檔。Don't include the app's executable in the path. 不需要結尾的斜線。A trailing slash isn't required.
  • {DOMAIN OR COMPUTER NAME\USER} – 服務使用者帳戶(例如,Contoso\ServiceUser)。{DOMAIN OR COMPUTER NAME\USER} – Service user account (for example, Contoso\ServiceUser).
  • {SERVICE NAME} – 服務名稱(例如,MyService)。{SERVICE NAME} – Service name (for example, MyService).
  • {EXE FILE PATH} – 應用程式的可執行檔路徑(例如,d:\myservice\myservice.exe)。{EXE FILE PATH} – The app's executable path (for example, d:\myservice\myservice.exe). 包含可執行檔的檔案名稱 (包含副檔名)。Include the executable's file name with extension.
  • {DESCRIPTION} – 服務描述(例如,My sample service)。{DESCRIPTION} – Service description (for example, My sample service).
  • {DISPLAY NAME} – 服務顯示名稱(例如,My Service)。{DISPLAY NAME} – Service display name (for example, My Service).

啟動服務Start a service

以下列 PowerShell 6 命令啟動服務:Start a service with the following PowerShell 6 command:

Start-Service -Name {SERVICE NAME}

此命令需要幾秒鐘啓動服務。The command takes a few seconds to start the service.

判斷服務的狀態Determine a service's status

若要檢查服務狀態,請使用下列 PowerShell 6 命令:To check the status of a service, use the following PowerShell 6 command:

Get-Service -Name {SERVICE NAME}

狀態會回報為下列值之一:The status is reported as one of the following values:

  • Starting
  • Running
  • Stopping
  • Stopped

停止服務Stop a service

使用下列 Powershell 6 命令停止服務:Stop a service with the following Powershell 6 command:

Stop-Service -Name {SERVICE NAME}

移除服務Remove a service

在停止服務的短暫延遲之後,請以下列 Powershell 6 命令移除服務:After a short delay to stop a service, remove a service with the following Powershell 6 command:

Remove-Service -Name {SERVICE NAME}

處理開始與停止事件Handle starting and stopping events

若要處理 OnStartingOnStartedOnStopping 事件:To handle OnStarting, OnStarted, and OnStopping events:

  1. 使用 WebHostServiceOnStartingOnStarted 方法建立衍生自 OnStopping 的類別:Create a class that derives from WebHostService with the OnStarting, OnStarted, and OnStopping methods:

    [DesignerCategory("Code")]
    internal class CustomWebHostService : WebHostService
    {
        private ILogger _logger;
    
        public CustomWebHostService(IWebHost host) : base(host)
        {
            _logger = host.Services
                .GetRequiredService<ILogger<CustomWebHostService>>();
        }
    
        protected override void OnStarting(string[] args)
        {
            _logger.LogInformation("OnStarting method called.");
            base.OnStarting(args);
        }
    
        protected override void OnStarted()
        {
            _logger.LogInformation("OnStarted method called.");
            base.OnStarted();
        }
    
        protected override void OnStopping()
        {
            _logger.LogInformation("OnStopping method called.");
            base.OnStopping();
        }
    }
    
  2. IWebHost 建立一個會將 CustomWebHostService 傳遞給 Run 的擴充方法:Create an extension method for IWebHost that passes the CustomWebHostService to Run:

    public static class WebHostServiceExtensions
    {
        public static void RunAsCustomService(this IWebHost host)
        {
            var webHostService = new CustomWebHostService(host);
            ServiceBase.Run(webHostService);
        }
    }
    
  3. Program.Main 中,呼叫 RunAsCustomService 擴充方法,而不是呼叫 RunAsServiceIn Program.Main, call the RunAsCustomService extension method instead of RunAsService:

    host.RunAsCustomService();
    

    若要查看 RunAsService 中的 Program.Main 位置,請參閱部署類型一節中的範例程式碼。To see the location of RunAsService in Program.Main, refer to the code sample shown in the Deployment type section.

Proxy 伺服器和負載平衡器案例Proxy server and load balancer scenarios

服務如果會與來自網際網路或公司網路的要求進行互動,並且位於 Proxy 或負載平衡器後方,可能會需要額外的設定。Services that interact with requests from the Internet or a corporate network and are behind a proxy or load balancer might require additional configuration. 如需詳細資訊,請參閱 設定 ASP.NET Core 以與 Proxy 伺服器和負載平衡器搭配運作For more information, see 設定 ASP.NET Core 以與 Proxy 伺服器和負載平衡器搭配運作.

設定端點Configure endpoints

ASP.NET Core 預設會繫結至 http://localhost:5000By default, ASP.NET Core binds to http://localhost:5000. 設定 ASPNETCORE_URLS 環境變數,以設定 URL 和埠。Configure the URL and port by setting the ASPNETCORE_URLS environment variable.

如需其他 URL 和埠設定方法,請參閱相關的伺服器文章:For additional URL and port configuration approaches, see the relevant server article:

前述指引涵蓋 HTTPS 端點的支援。The preceding guidance covers support for HTTPS endpoints. 例如,當搭配 Windows 服務使用驗證時,請為 HTTPS 設定應用程式。For example, configure the app for HTTPS when authentication is used with a Windows Service.

注意

不支援使用 ASP.NET Core HTTPS 開發憑證來保護服務端點。Use of the ASP.NET Core HTTPS development certificate to secure a service endpoint isn't supported.

目前目錄和內容根目錄Current directory and content root

針對 Windows 服務呼叫 GetCurrentDirectory 所傳回的目前工作目錄為 C:\WINDOWS\system32 資料夾。The current working directory returned by calling GetCurrentDirectory for a Windows Service is the C:\WINDOWS\system32 folder. System32 資料夾不是儲存服務檔案 (例如,設定檔) 的合適位置。The system32 folder isn't a suitable location to store a service's files (for example, settings files). 使用下列其中一個方式來維護及存取服務的資產與設定檔。Use one of the following approaches to maintain and access a service's assets and settings files.

將內容根目錄路徑設定到應用程式的資料夾Set the content root path to the app's folder

ContentRootPath 與建立服務時提供給 binPath 引數的路徑相同。The ContentRootPath is the same path provided to the binPath argument when a service is created. 請呼叫具有應用程式內容根目錄路徑的 SetCurrentDirectory,而不是呼叫 GetCurrentDirectory 建立設定檔的路徑。Instead of calling GetCurrentDirectory to create paths to settings files, call SetCurrentDirectory with the path to the app's content root.

Program.Main 中,判斷服務可執行檔資料夾的路徑,然後使用該路徑來建立應用程式的內容根目錄:In Program.Main, determine the path to the folder of the service's executable and use the path to establish the app's content root:

var pathToExe = Process.GetCurrentProcess().MainModule.FileName;
var pathToContentRoot = Path.GetDirectoryName(pathToExe);
Directory.SetCurrentDirectory(pathToContentRoot);

CreateWebHostBuilder(args)
    .Build()
    .RunAsService();

將服務的檔案儲存在磁碟上的適當位置Store a service's files in a suitable location on disk

使用包含檔案的 SetBasePath 資料夾,使用 IConfigurationBuilder 來指定絕對路徑。Specify an absolute path with SetBasePath when using an IConfigurationBuilder to the folder containing the files.

疑難排解Troubleshoot

若要疑難排解 Windows 服務應用程式,請參閱 疑難排解和調試 ASP.NET Core 專案To troubleshoot a Windows Service app, see 疑難排解和調試 ASP.NET Core 專案.

常見錯誤Common errors

  • 舊版或發行前版本的 PowerShell 已在使用中。An old or pre-release version of PowerShell is in use.
  • 已註冊的服務不會使用來自dotnet publish命令的應用程式已發佈輸出。The registered service doesn't use the app's published output from the dotnet publish command. 應用程式部署不支援dotnet build命令的輸出。Output of the dotnet build command isn't supported for app deployment. 根據部署類型,可以在下列其中一個資料夾中找到已發佈的資產:Published assets are found in either of the following folders depending on the deployment type:
    • bin/Release/{TARGET FRAMEWORK}/publish (FDD)bin/Release/{TARGET FRAMEWORK}/publish (FDD)
    • bin/Release/{TARGET FRAMEWORK}/{RUNTIME IDENTIFIER}/publish (SCD)bin/Release/{TARGET FRAMEWORK}/{RUNTIME IDENTIFIER}/publish (SCD)
  • 服務不是處於執行中狀態。The service isn't in the RUNNING state.
  • 應用程式所使用資源的路徑(例如憑證)不正確。The paths to resources that the app uses (for example, certificates) are incorrect. Windows 服務的基底路徑是c:\windows\System32The base path of a Windows Service is c:\Windows\System32.
  • 使用者不具有 [以服務方式登入] 許可權。The user doesn't have Log on as a service rights.
  • 執行 New-Service PowerShell 命令時,使用者的密碼已過期或傳遞錯誤。The user's password is expired or incorrectly passed when executing the New-Service PowerShell command.
  • 應用程式需要 ASP.NET Core 驗證,但未設定安全連線(HTTPS)。The app requires ASP.NET Core authentication but isn't configured for secure connections (HTTPS).
  • 要求 URL 埠不正確,或未在應用程式中正確設定。The request URL port is incorrect or not configured correctly in the app.

系統和應用程式事件記錄檔System and Application Event Logs

存取系統和應用程式事件記錄檔:Access the System and Application Event Logs:

  1. 開啟 [開始] 功能表,搜尋 [事件檢視器],然後選取 [事件檢視器] 應用程式。Open the Start menu, search for Event Viewer, and select the Event Viewer app.
  2. 在 [事件檢視器] 中,開啟 [Windows 記錄] 節點。In Event Viewer, open the Windows Logs node.
  3. 選取 [系統] 以開啟 [系統] 事件記錄檔。Select System to open the System Event Log. 選取 [應用程式] 以開啟「應用程式事件記錄檔」。Select Application to open the Application Event Log.
  4. 搜尋與失敗應用程式相關的錯誤。Search for errors associated with the failing app.

在命令提示字元中執行應用程式Run the app at a command prompt

許多啟動錯誤不會在事件記錄檔中產生有用的資訊。Many startup errors don't produce useful information in the event logs. 您可以藉由在主控系統上的命令提示字元中執行應用程式,來找出一些錯誤的原因。You can find the cause of some errors by running the app at a command prompt on the hosting system. 若要從應用程式記錄其他詳細資料,請降低記錄層級,或在開發環境中執行應用程式。To log additional detail from the app, lower the log level or run the app in the Development environment.

清除套件快取Clear package caches

升級開發電腦上的 .NET Core SDK 或變更應用程式內的套件版本之後,正常運作的應用程式可能會立即失敗。A functioning app may fail immediately after upgrading either the .NET Core SDK on the development machine or changing package versions within the app. 在某些情況下,執行主要升級時,不一致的套件可能會中斷應用程式。In some cases, incoherent packages may break an app when performing major upgrades. 大多數這些問題都可依照下列指示來進行修正:Most of these issues can be fixed by following these instructions:

  1. 刪除 [bin] 和 [obj] 資料夾。Delete the bin and obj folders.

  2. 從命令 shell 執行dotnet nuget 區域變數 all--clear ,以清除套件快取。Clear the package caches by executing dotnet nuget locals all --clear from a command shell.

    您也可以使用nuget.exe工具來完成清除套件快取,並 nuget locals all -clear執行命令。Clearing package caches can also be accomplished with the nuget.exe tool and executing the command nuget locals all -clear. nuget.exe 並未隨附在 Windows 桌面作業系統的安裝中,必須另外從 NuGet 網站取得。nuget.exe isn't a bundled install with the Windows desktop operating system and must be obtained separately from the NuGet website.

  3. 還原並重建專案。Restore and rebuild the project.

  4. 重新部署應用程式之前,請先刪除伺服器上 [部署] 資料夾中的所有檔案。Delete all of the files in the deployment folder on the server prior to redeploying the app.

回應緩慢或無回應的應用程式Slow or hanging app

傾印是系統記憶體的快照集,有助於判斷應用程式損毀、啟動失敗或應用程式緩慢的原因。A crash dump is a snapshot of the system's memory and can help determine the cause of an app crash, startup failure, or slow app.

應用程式損毀或發生例外狀況App crashes or encounters an exception

Windows 錯誤報告 (WER) 取得並分析傾印:Obtain and analyze a dump from Windows Error Reporting (WER):

  1. c:\dumps 中建立資料夾以保存損毀傾印檔案。Create a folder to hold crash dump files at c:\dumps.

  2. 以應用程式可執行檔名稱執行EnableDumps PowerShell 腳本Run the EnableDumps PowerShell script with the application executable name:

    .\EnableDumps {APPLICATION EXE} c:\dumps
    
  3. 在會導致損毀的情況下,執行應用程式。Run the app under the conditions that cause the crash to occur.

  4. 發生損毀之後,請執行 DisableDumps PowerShell 指令碼After the crash has occurred, run the DisableDumps PowerShell script:

    .\DisableDumps {APPLICATION EXE}
    

在應用程式損毀且傾印收集完成之後,即可正常結束應用程式。After an app crashes and dump collection is complete, the app is allowed to terminate normally. PowerShell 指令碼會將 WER 設定為每個應用程式收集最多五個傾印。The PowerShell script configures WER to collect up to five dumps per app.

警告

損毀傾印可能會佔用大量磁碟空間 (每個高達好幾 GB)。Crash dumps might take up a large amount of disk space (up to several gigabytes each).

應用程式停止回應、在啟動期間失敗,或正常執行App hangs, fails during startup, or runs normally

應用程式當機(停止回應但未損毀)、啟動期間失敗,或正常執行時,請參閱使用者模式傾印檔案:選擇最適合的工具來選取適當的工具以產生傾印。When an app hangs (stops responding but doesn't crash), fails during startup, or runs normally, see User-Mode Dump Files: Choosing the Best Tool to select an appropriate tool to produce the dump.

分析傾印Analyze the dump

您可以使用數種方法來分析傾印。A dump can be analyzed using several approaches. 如需詳細資訊,請參閱分析使用者模式傾印檔案For more information, see Analyzing a User-Mode Dump File.

其他資源Additional resources