Skapa en tjänst för Windows i .NET 8

Sidan uppdaterad :
Datum för skapande av sida :

Omvärld

Visuell studio
  • Visual Studio 2022
.NÄT
  • .NET 8
Windows
  • Windows 11 (på engelska)

Förutsättningar

Visuell studio
  • Visual Studio 2022
.NÄT
  • .NET 8
Windows
  • Windows 10 (på engelska)
  • Windows 11 (på engelska)
Windows Server
  • Windows 2012 eller senare

förutsättning

  • Visual Studio är redan installerat

Först

När jag försöker skapa en Windows-tjänst i Visual Studio .NET finns det bara .NET Framework mallar. Den kan också skapas i .NET (Core) och mallen heter "Worker Service".

I den här artikeln kommer jag att förklara hur man använder detta för att skapa, registrera och köra en Windows-tjänst. Bearbetningsinnehållet är minimalt, så om du kan bekräfta att det körs som en Windows-tjänst skapar du funktionen.

Skapa ett projekt

Starta Visual Studio. Välj Skapa ett nytt projekt.

Ange i サービス sökfältet ovan och välj sedan Arbetstjänst i listan. "Windows-tjänster" är den .NET Framework-version som inte har någon .

Projektets namn och plats kan vara godtyckliga. Det påverkar inte den tjänst du registrerar dig för.

「. NET 8.0 är markerat och lämna standardinställningarna för att skapa det.

Projektet har skapats.

Lägga till bibliotek

I det ursprungliga tillståndet har den bara en "tjänst"-funktion och inga Windows-specifika funktioner. Lägg till ett bibliotek som kan användas av en Windows-tjänst från NuGet.

Högerklicka på Beroenden och välj Hantera NuGet-paket.

Välj fliken Bläddra och ange i Microsoft.Extensions.Hosting.WindowsServices sökfältet. Det kommer att visas i listan, så installera det.

Klicka på Använd.

Det lades till som ett paket.

Redigera program

Den här gången kommer jag att skapa en tjänst som med jämna mellanrum lägger till text i en textfil som en Mr./Ms..

Program.cs

Lägg till funktionerna i Windows-tjänsten på följande sätt:

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

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

Worker.cs

Du kan ändra klassnamnet godtyckligt, men för den här gången lämnar vi standard.

Som standard finns det bara metoder som ExecuteAsync bearbetas när tjänsten körs, men låt oss ändra det på följande sätt:

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);
    }
  }
}

Vi har lagt till en ny metod och StopAsync en ny StartAsync metod. Som namnet antyder anropas dessa metoder när tjänsten startas och när den stoppas. Innehållet i processen är helt enkelt att skapa mappar och skriva text, så jag kommer att utelämna förklaringen.

ExecuteAsync Metoden fortsätter att loopa med stoppingToken tills while den flaggas för annullering. Lägg till det while du vill ska bearbetas medan tjänsten körs. Men om du bara skriver den process du vill flytta kommer tjänsten att köras med full kapacitet, så Task.Delay det är grundläggande att flytta den medan du väntar på en viss tid med metoden. Som standard är den inställd på 1 sekund (1000ms), så skriv om den när som helst.

felsöka

Du kan felsöka från Visual Studio. Du kan vara säker på att du inte kommer att registreras i tjänsten.

När du kör den kommer konsolen att visas.

Om processen är korrekt kan du se att filen har skapats.

Om du vill stoppa felsökningen stänger du konsolen.

Om du kontrollerar loggen kan du se att tjänstens startprocess har godkänts, men att avslutningsprocessen inte har gjort det. För att se uppsägningen måste du registrera dig hos Windows-tjänsten för att verifiera den.

utfärda

För att kunna registrera dig med en Windows-tjänst måste du publicera programmet. Högerklicka på projektet och välj Publicera.

Välj Mappar.

Mappens plats är trevlig som standard.

Publiceringsinställningarna kommer att skapas, så välj "Visa alla inställningar".

Ställ in det på följande sätt:

Parameternamn Värde Kommentarer
konfiguration Frisläpp (standard)
Ramverk för mål net8.0 (standard)
Distributions lägen Ramverks-beroende Separat för tjänstregistreringsmiljön. Om du installerar NEt 8 runtime är den här inställningen OK.
Målkörning vinna-x64 Om operativsystemet är en 32-bitarsmiljö väljer du win-x86
Målplats standard
Skapa en enskild fil
ReadyToRun-kompilering godtycklig

Efter inställningen klickar du på knappen "Skicka".

Om "Publiceringen lyckades" visas i det nedre vänstra hörnet är den klar.

Utdatafilen kan öppnas genom att klicka på "Målplats".

Programplacering och registrering i tjänster

Logga in i den miljö där du vill registrera Windows-tjänsten med administratörsbehörighet.

Kopiera den publicerade filen till den miljö där du vill registrera den som en Windows-tjänst. Du kan placera den i vilken mapp som helst, men tänk på att Windows-tjänsten alltid kommer att referera till programmet i den mappen.

Om den publicerade filen innehåller en fil med filändelsen .pdb ska du inte kopiera den i en miljö där den kan ses av en ospecificerad person eftersom den innehåller utvecklingsinformation.

När filen är på plats registrerar du den som en Windows-tjänst. Använd kommandot för att registrera dig. Högerklicka på Start-menyn och välj "Terminal (Admin)". Mr./Ms. körs i en Windows 11-miljö, men i andra miljöer är det OK att öppna en kommandotolk med administratörsbehörighet.

När det gäller terminalen kan PowerShell vara öppet först, men PowerShell kanske inte kan konfigurera det korrekt, så öppna "Kommandotolken".

Du kan registrera den med Windows-tjänsten med följande kommando:

format

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

Exempel på indata

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

<サービス名> är det namn som visas i listan över Windows-tjänster. Du kan ange ett separat visningsnamn, men om du inte anger ett visningsnamn visas detta namn. Det påverkar också registret, så alfanumeriska tjänstnamn är att föredra.

start=auto är en inställning för att automatiskt starta tjänsten när Windows startar. Om du vill starta den manuellt tar du bort den här beskrivningen.

binpath är den fullständiga sökvägen till programfilerna.

Om du kör kommandot och [SC] CreateService SUCCESS visar , det lyckas.

De tjänster du har registrerat bör visas i listan.

Starta tjänsten och kontrollera att den fungerar

Om du vill köra tjänsten kan du starta den från tjänstskärmen eller med följande kommando.

sc start <サービス名>

Stoppkommandot är som följer.

sc stop <サービス名>

Om du stoppar tjänsten kan du kontrollera att avstängningsprocessen körs.

Lägga till en beskrivning i tjänsten

Beskrivningsfältet för den tillagda tjänsten är tomt, men du kan lägga till det med följande kommando.

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

Ta bort en tjänst

Om du vill ta bort tjänsten kan du göra det med följande kommando. Du måste ha administratörsbehörighet i kommandotolken.

sc delete <サービス名>