Een service voor Windows maken in .NET 8

Pagina bijgewerkt :
Aanmaakdatum van pagina :

Werkomgeving

Visuele Studio
  • Visuele Studio 2022
.NET
  • .NET 8
Ramen
  • Windows 11

Voorwaarden

Visuele Studio
  • Visuele Studio 2022
.NET
  • .NET 8
Ramen
  • Vensters 10
  • Windows 11
Windows Server
  • Windows 2012 of hoger

voorwaarde

  • Visual Studio is al geïnstalleerd

Eerst

Wanneer ik een Windows-service probeer te maken in Visual Studio .NET, zijn er alleen .NET Framework-sjablonen. Het kan ook worden gemaakt in .NET (Core) en de sjabloon heeft de naam "Worker Service".

In dit artikel leg ik uit hoe je dit kunt gebruiken om een Windows-service te maken, te registreren en uit te voeren. De verwerkingsinhoud is minimaal, dus als u kunt bevestigen dat het wordt uitgevoerd als een Windows-service, maak dan de functie.

Een project maken

Start Visual Studio. Selecteer Een nieuw project maken.

Typ in het サービス zoekveld hierboven en selecteer vervolgens Werknemersservice in de lijst. "Windows Services" is de .NET Framework-versie, die geen .NET-versie heeft.

De naam en locatie van het project kunnen willekeurig zijn. Het heeft geen invloed op de service waarvoor u zich registreert.

「. NET 8.0 is geselecteerd en laat de standaardwaarden staan om deze te maken.

Het project is in het leven geroepen.

Bibliotheken toevoegen

In de begintoestand heeft het alleen een "service" -functie en geen Windows-specifieke functies. Voeg een bibliotheek toe die kan worden gebruikt door een Windows-service van NuGet.

Klik met de rechtermuisknop op Afhankelijkheden en selecteer NuGet-pakketten beheren.

Selecteer het tabblad Bladeren en voer het Microsoft.Extensions.Hosting.WindowsServices zoekveld in. Het verschijnt in de lijst, dus installeer het.

Klik op Toepassen.

Het is toegevoegd als een pakket.

Programma's bewerken

Deze keer zal ik een service maken die periodiek tekst toevoegt aan een tekstbestand als een meneer/mevrouw.

Program.cs

Voeg de functionaliteit van de Windows-service als volgt toe:

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

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

Worker.cs

Je kunt de naam van de klas willekeurig wijzigen, maar voor deze keer laten we de standaardwaarde staan.

Standaard zijn er alleen methoden die worden ExecuteAsync verwerkt wanneer de service wordt uitgevoerd, maar laten we dit als volgt wijzigen:

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

We hebben een nieuwe methode en StopAsync een nieuwe StartAsync methode toegevoegd. Zoals de naam al aangeeft, worden deze methoden aangeroepen wanneer de service wordt gestart en wanneer deze wordt gestopt. De inhoud van het proces is simpelweg het maken van mappen en het schrijven van tekst, dus ik zal de uitleg achterwege laten.

ExecuteAsync De methode blijft herhalen met stoppingToken totdat while deze is gemarkeerd voor annulering. Voeg toe wat while u wilt laten verwerken terwijl de service actief is. Als u echter alleen het proces schrijft dat u wilt verplaatsen, draait de service op volle capaciteit, dus Task.Delay het is eenvoudig om het te verplaatsen terwijl u een bepaalde tijd wacht met de methode. Standaard is het ingesteld op 1 seconde (1000 ms), dus herschrijf het op elk moment.

debuggen

U kunt fouten opsporen vanuit Visual Studio. U kunt er zeker van zijn dat u niet daadwerkelijk bij de service wordt geregistreerd.

Wanneer u het uitvoert, verschijnt de console.

Als het proces correct is, kunt u zien dat het bestand is gemaakt.

Als u wilt stoppen met foutopsporing, sluit u de console.

Als u het logboek controleert, kunt u zien dat het startproces van de service is geslaagd, maar het beëindigingsproces niet. Als u de beëindiging wilt zien, moet u zich daadwerkelijk registreren bij de Windows-service om deze te verifiëren.

uitgeven

Om u te kunnen registreren bij een Windows-service, moet u het programma publiceren. Klik met de rechtermuisknop op het project en kies Publiceren.

Selecteer Mappen.

De maplocatie is standaard prettig.

De publicatie-instellingen worden gemaakt, dus selecteer "Toon alle instellingen".

Stel het als volgt in:

Parameter, Naam, Waarde Opmerkingen,
configuratie Vrijgave (standaard)
Streefkader net8.0 (standaard)
Implementatie modi Afhankelijkheid van het framework Apart voor de service registratie omgeving. Als u de NEt 8-runtime installeert, is deze instelling OK.
Doellooptijd win-x64 Als het besturingssysteem een 32-bits omgeving is, selecteert u win-x86
Doellocatie verstek
Een enkel bestand maken OP
ReadyToRun-compilatie arbitrair

Klik na het instellen op de knop "Verzenden".

Als "Publiceren is gelukt" in de linkerbenedenhoek wordt weergegeven, is het voltooid.

Het uitvoerbestand kan worden geopend door op "Doellocatie" te klikken.

Plaatsing van het programma en inschrijving in services

Log in op de omgeving waar je de Windows-dienst met beheerdersrechten wilt registreren.

Kopieer het gepubliceerde bestand naar de omgeving waarin u het als Windows-service wilt registreren. Je kunt het in elke map plaatsen, maar houd er rekening mee dat de Windows-service altijd verwijst naar het programma in die map.

Als het gepubliceerde bestand een bestand met de extensie .pdb bevat, kopieer het dan niet in een omgeving waar het door een niet-gespecificeerde persoon kan worden gezien, omdat het ontwikkelingsinformatie bevat.

Zodra het bestand op zijn plaats is, registreert u het als een Windows-service. Gebruik de opdracht om te registreren. Klik met de rechtermuisknop op het menu Start en selecteer "Terminal (Admin)". Dhr./Ms. draait in een Windows 11-omgeving, maar in andere omgevingen is het OK om een opdrachtprompt met beheerdersrechten te openen.

In het geval van de terminal is PowerShell mogelijk eerst geopend, maar PowerShell kan deze mogelijk niet correct instellen, dus open de "Opdrachtprompt".

U kunt het registreren bij de Windows-service met de volgende opdracht:

formatteren

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

Voorbeeld invoer

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

<サービス名> is de naam die voorkomt in de lijst met Windows-services. U kunt een aparte weergavenaam instellen, maar als u geen weergavenaam opgeeft, wordt deze naam weergegeven. Het heeft ook invloed op het register, dus alfanumerieke servicenamen hebben de voorkeur.

start=auto is een instelling om de service automatisch te starten wanneer Windows wordt gestart. Als u het handmatig wilt starten, verwijdert u deze beschrijving.

binpath is het volledige pad van de programmabestanden.

Als u de opdracht uitvoert en [SC] CreateService SUCCESS weergeeft, is deze geslaagd.

De services die u hebt geregistreerd, zouden in de lijst moeten verschijnen.

Start de service en controleer de werking ervan

Als u de service wilt uitvoeren, kunt u deze starten vanaf het servicescherm of met de volgende opdracht.

sc start <サービス名>

Het stopcommando is als volgt.

sc stop <サービス名>

Als u de service stopt, kunt u controleren of het afsluitproces wordt uitgevoerd.

Voeg een beschrijving toe aan de service

Het beschrijvingsveld van de toegevoegde service is leeg, maar u kunt het toevoegen met de volgende opdracht.

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

Een service verwijderen

Als u de service wilt verwijderen, kunt u dit doen met de volgende opdracht. U moet beheerdersrechten hebben bij de opdrachtprompt.

sc delete <サービス名>