在 .NET 8 中創建適用於 Windows 的服務Create a service for Windows in .NET 8

更新頁 :
頁面創建日期 :

操作環境

Visual Studio的
  • Visual Studio 2022
。網
  • .NET 8
窗戶
  • 窗戶11

先決條件

Visual Studio的
  • Visual Studio 2022
。網
  • .NET 8
窗戶
  • 窗戶10
  • 窗戶11
Windows 伺服器
  • Windows 2012 或更高版本

前提

  • 已安裝 Visual Studio

起先

當我嘗試在Visual Studio.NET中創建 Windows 服務時,只有 .NET Framework 範本。 它也可以在 .NET (Core) 中創建,範本名為“Worker Service”。

在本文中,我將解釋如何使用它來創建、註冊和運行 Windows 服務。 處理內容很少,因此,如果您可以確認它作為 Windows 服務運行,請創建函數。

創建專案

啟動 Visual Studio。 選擇「創建新專案」。

在上面的 サービス 搜索欄位中輸入,然後從清單中選擇「輔助角色服務」。 “Windows 服務”是 .NET Framework 版本,它沒有 .NET 版本。

項目名稱和位置可以是任意的。 它不會影響您正在註冊的服務。

「. 選擇 NET 8.0,並保留預設值以創建它。

專案已創建。

添加庫

在初始狀態下,它只有一個“服務”功能,沒有Windows特定的功能。 從 NuGet 添加可供 Windows 服務使用的庫。

右鍵按兩下「依賴項」,然後選擇「管理 NuGet 包」。

選擇「瀏覽」選項卡, Microsoft.Extensions.Hosting.WindowsServices 然後在搜索欄位中輸入。 它將出現在清單中,因此請安裝它。

按兩下應用。

它已作為包添加。

編輯程式

這一次,我將創建一個服務,該服務定期將文本作為 Mr./Ms. 添加到文本檔中。

Program.cs

添加 Windows 服務的功能,如下所示:

var builder = Host.CreateApplicationBuilder(args);
// ↓ここから追加
builder.Services.AddWindowsService();
// ↑ここまで追加
builder.Services.AddHostedService<Worker>();

var host = builder.Build();
host.Run();

Worker.cs

您可以任意更改類名,但這次我們將保留預設值。

默認情況下,只有一些方法在 ExecuteAsync 執行服務時進行處理,但讓我們按如下方式進行更改:

public class Worker : BackgroundService
{
  private readonly ILogger<Worker> _logger;

  /// <summary>ログの出力先フォルダパス。</summary>
  private const string OutputLogFolderPath = @"C:\Temporary\";

  /// <summary>ログの出力先ファイルパス。</summary>
  private const string OutputLogFilePath = @$"{OutputLogFolderPath}Test.log";


  public Worker(ILogger<Worker> logger)
  {
    _logger = logger;
  }

  /// <summary>
  /// サービスが開始されたときに呼ばれます。
  /// </summary>
  /// <param name="stoppingToken"></param>
  /// <returns></returns>
  public override async Task StartAsync(CancellationToken stoppingToken)
  {
    if (Directory.Exists(OutputLogFolderPath) == false)
    {
      Directory.CreateDirectory(OutputLogFolderPath);
    }
    File.AppendAllText(OutputLogFilePath, $"StartAsync サービスを開始しました。\r\n");

    await base.StartAsync(stoppingToken);
  }

  /// <summary>
  /// サービスが終了したときに呼ばれます。
  /// </summary>
  /// <param name="stoppingToken"></param>
  /// <returns></returns>
  public override async Task StopAsync(CancellationToken stoppingToken)
  {
    File.AppendAllText(OutputLogFilePath, $"StopAsync サービスを終了しました。\r\n");
    File.AppendAllText(OutputLogFilePath, $"------------------------------\r\n");

    await base.StopAsync(stoppingToken);
  }

  /// <summary>
  /// サービスが実行されたときに呼ばれます。
  /// </summary>
  /// <param name="stoppingToken">サービスの非同期キャンセルトークン。</param>
  /// <returns></returns>
  protected override async Task ExecuteAsync(CancellationToken stoppingToken)
  {
    while (!stoppingToken.IsCancellationRequested)
    {
      File.AppendAllText(OutputLogFilePath, $"{DateTime.Now}\r\n");

      if (_logger.IsEnabled(LogLevel.Information))
      {
        _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
      }
      await Task.Delay(1000 * 60, stoppingToken);
    }
  }
}

我們添加了一個新方法和StopAsync一個新StartAsync方法。 顧名思義,這些方法在服務啟動和停止時被調用。 該過程的內容只是創建資料夾和編寫文字,因此我將省略解釋。

ExecuteAsync 該方法繼續使用 stoppingToken 迴圈,直到 while 它被標記為取消。 添加要在服務運行時進行處理的內容 while 。 但是,如果只編寫要移動的進程,則服務將滿負荷運行,因此 Task.Delay 使用該方法在等待一定時間的同時移動它是基本的。 默認情況下,它設置為1秒(1000毫秒),因此請隨時重寫。

調試

可以從 Visual Studio 進行調試。 請放心,您實際上不會註冊該服務。

當您運行它時,主控台將出現。

如果該過程正確,您可以看到檔已創建。

如果要停止調試,請關閉主控台。

如果檢查日誌,可以看到服務啟動過程已通過,但終止過程尚未通過。 要查看終止,您需要實際註冊 Windows 服務以驗證它。

問題

為了能夠向 Windows 服務註冊,您必須發佈該程式。 右鍵按下專案,然後選擇“發佈”。

選擇資料夾。

默認情況下,資料夾位置很好。

將創建發佈設置,因此請選擇“顯示所有設置”。

按如下方式進行設置:

參數名稱 值 註
配置 釋放(預設)
目標框架 net8.0 (預設)
部署模式 框架依賴性 單獨用於服務註冊環境。 如果要安裝 NEt 8 執行時,則此設置是可以的。
目標運行時 贏-x64 如果操作系統是32位環境,請選擇 win-x86
目標位置 違約
創建單個檔
ReadyToRun 編譯 任意

設置完成後,點擊「提交」按鈕。

如果左下角顯示「發佈成功」 則表示發佈成功。

可以通過按兩下目標位置來打開輸出檔。

課程安排和服務註冊

以管理員許可權登錄到要註冊 Windows 服務的環境。

將發佈的檔複製到要將其註冊為 Windows 服務的環境中。 您可以將其放置在任何資料夾中,但請記住,Windows 服務將始終引用該資料夾中的程式。

此外,如果發佈的檔包含擴展名為 .pdb 的檔,請不要在可以被未指定人員看到的環境中複製它,因為它包含開發資訊。

檔就位后,將其註冊為 Windows 服務。 使用命令進行註冊。 右鍵按鍵單擊「開始」功能表,然後選擇「終端(管理員)」。 Mr./Ms. 在 Windows 11 環境中運行,但在其他環境中,可以使用管理員許可權打開命令提示符。

對於終端,PowerShell 可能會先打開,但 PowerShell 可能無法正確設置,因此請打開“命令提示符”。

您可以使用以下命令將其註冊到 Windows 服務中:

格式

sc create "<サービス名>" start=auto binpath="<プログラム(.exe)のパス>"

示例輸入

sc create "WindowsServiceDotNet8" start=auto binpath="C:\Service\WindowsServiceDotNet8\WindowsServiceDotNet8.exe"

<サービス名> 是顯示在 Windows 服務清單中的名稱。 您可以設置單獨的顯示名稱,但如果未指定顯示名稱,則將顯示此名稱。 它還會影響註冊表,因此首選字母數位服務名稱。

start=auto 是在 Windows 啟動時自動啟動服務的設置。 如果要手動啟動它,請刪除此說明。

binpath 是程式檔的完整路徑。

如果執行命令並 [SC] CreateService SUCCESS 顯示 ,則表示成功。

您註冊的服務應顯示在清單中。

啟動服務並檢查其操作

如果要運行該服務,可以從服務螢幕或使用以下命令啟動它。

sc start <サービス名>

stop 命令如下。

sc stop <サービス名>

如果停止該服務,則可以驗證關閉進程是否正在運行。

向服務添加說明

已添加服務的描述欄位為空,但您可以使用以下命令進行添加。

sc description <サービス名> "<説明文>"

刪除服務

如果要刪除服務,可以使用以下命令執行此操作。 您必須在命令提示符下具有管理員許可權。

sc delete <サービス名>