Créer un service pour Windows dans .NET 8

Page mise à jour :
Date de création de la page :

Environnement d’exploitation

Studio visuel
  • Visual Studio 2022
.FILET
  • .NET 8
Windows
  • Windows 11

Conditions préalables

Studio visuel
  • Visual Studio 2022
.FILET
  • .NET 8
Windows
  • Windows 10
  • Windows 11
Serveur Windows
  • Windows 2012 ou version ultérieure

condition préalable

  • Visual Studio est déjà installé

Au début

Lorsque j’essaie de créer un service Windows dans Visual Studio .NET, il n’existe que des modèles .NET Framework. Il peut également être créé dans .NET (Core) et le modèle est nommé « Worker Service ».

Dans cet article, je vais vous expliquer comment l’utiliser pour créer, enregistrer et exécuter un service Windows. Le contenu de traitement est minimal, donc si vous pouvez confirmer qu’il s’exécute en tant que service Windows, veuillez créer la fonction.

Créer un projet

Démarrez Visual Studio. Sélectionnez Créer un projet.

Entrez dans le champ de サービス recherche ci-dessus, puis sélectionnez Service de travail dans la liste. « Services Windows » est la version du .NET Framework, qui n’a pas de version .NET.

Le nom et l’emplacement du projet peuvent être arbitraires. Cela n’affecte pas le service auquel vous vous inscrivez.

「. NET 8.0 est sélectionné et laissez les valeurs par défaut pour le créer.

Le projet a été créé.

Ajout de bibliothèques

Dans l’état initial, il ne dispose que d’une fonction « service » et aucune fonction spécifique à Windows. Ajoutez une bibliothèque qui peut être utilisée par un service Windows à partir de NuGet.

Cliquez avec le bouton droit sur Dépendances et sélectionnez Gérer les packages NuGet.

Sélectionnez l’onglet Parcourir et entrez dans le champ de Microsoft.Extensions.Hosting.WindowsServices recherche. Il apparaîtra dans la liste, alors installez-le.

Cliquez sur Appliquer.

Il a été ajouté sous forme de package.

Édition de programmes

Cette fois, je vais créer un service qui ajoute périodiquement du texte à un fichier texte en tant que M./Mme.

Program.cs

Ajoutez les fonctionnalités du service Windows comme suit :

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

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

Worker.cs

Vous pouvez modifier le nom de la classe arbitrairement, mais pour cette fois, nous laisserons la valeur par défaut.

Par défaut, seules les méthodes sont ExecuteAsync traitées lors de l’exécution du service, mais modifions-la comme suit :

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

Nous avons ajouté une nouvelle méthode et StopAsync une nouvelle StartAsync méthode. Comme leur nom l’indique, ces méthodes sont appelées lorsque le service est démarré et lorsqu’il est arrêté. Le contenu du processus consiste simplement à créer des dossiers et à écrire du texte, je vais donc omettre l’explication.

ExecuteAsync La méthode continue de boucler avec stoppingToken jusqu’à ce qu’elle while soit marquée pour annulation. Ajoutez ce que while vous souhaitez traiter pendant l’exécution du service. Cependant, si vous n’écrivez que le processus que vous souhaitez déplacer, le service fonctionnera à pleine capacité, il est donc Task.Delay fondamental de le déplacer en attendant un certain temps avec la méthode. Par défaut, il est défini sur 1 seconde (1000 ms), veuillez donc le réécrire à tout moment.

déboguer

Vous pouvez déboguer à partir de Visual Studio. Soyez assuré que vous ne serez pas réellement inscrit au service.

Lorsque vous l’exécutez, la console apparaît.

Si le processus est correct, vous pouvez voir que le fichier a été créé.

Si vous souhaitez arrêter le débogage, fermez la console.

Si vous consultez le journal, vous pouvez voir que le processus de démarrage du service a réussi, mais pas le processus de terminaison. Pour voir la résiliation, vous devez vous inscrire auprès du service Windows pour la vérifier.

émettre

Pour pouvoir s’inscrire auprès d’un service Windows, vous devez publier le programme. Cliquez avec le bouton droit sur le projet et choisissez Publier.

Sélectionnez Dossiers.

L’emplacement du dossier est correct par défaut.

Les paramètres de publication seront créés, alors sélectionnez « Afficher tous les paramètres ».

Configurez-le comme suit :

Nom du paramètre Valeur Remarques
configuration Libération (par défaut)
Cadre cible net8.0 (par défaut)
Modes de déploiement Dépendance du cadre Séparément pour l’environnement d’inscription du service. Si vous installez le runtime NEt 8, ce paramètre est OK.
Temps d’exécution cible win-x64 Si le système d’exploitation est un environnement 32 bits, sélectionnez win-x86
Emplacement cible faire défaut
Création d’un seul fichier SUR
ReadyToRun Compilation arbitraire

Après le réglage, cliquez sur le bouton « Soumettre ».

Si l’option « Réussite de la publication » s’affiche dans le coin inférieur gauche, cela signifie qu’elle est terminée.

Le fichier de sortie peut être ouvert en cliquant sur « Emplacement cible ».

Placement dans le programme et inscription aux services

Connectez-vous à l’environnement dans lequel vous souhaitez inscrire le service Windows avec des privilèges d’administrateur.

Copiez le fichier publié dans l’environnement dans lequel vous souhaitez l’inscrire en tant que service Windows. Vous pouvez le placer dans n’importe quel dossier, mais gardez à l’esprit que le service Windows fera toujours référence au programme dans ce dossier.

De plus, si le fichier publié contient un fichier avec l’extension .pdb , ne le copiez pas dans un environnement où il peut être vu par une personne non spécifiée, car il contient des informations de développement.

Une fois le fichier en place, enregistrez-le en tant que service Windows. Utilisez la commande pour vous inscrire. Faites un clic droit sur le menu Démarrer et sélectionnez « Terminal (Admin) ». M./Mme s’exécute dans un environnement Windows 11, mais dans d’autres environnements, il est OK d’ouvrir une invite de commande avec des privilèges d’administrateur.

Dans le cas du terminal, PowerShell peut être ouvert en premier, mais PowerShell peut ne pas être en mesure de le configurer correctement, alors ouvrez l'« invite de commande ».

Vous pouvez l’enregistrer auprès du service Windows à l’aide de la commande suivante :

format

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

Exemple d’entrée

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

<サービス名> est le nom qui apparaît dans la liste des services Windows. Vous pouvez définir un nom d’affichage distinct, mais si vous ne spécifiez pas de nom d’affichage, ce nom sera affiché. Cela affecte également le registre, de sorte que les noms de service alphanumériques sont préférés.

start=auto est un paramètre permettant de démarrer automatiquement le service au démarrage de Windows. Si vous souhaitez le démarrer manuellement, supprimez cette description.

binpath est le chemin d’accès complet des fichiers programme.

Si vous exécutez la commande et [SC] CreateService SUCCESS affichez , elle réussit.

Les services que vous avez enregistrés doivent apparaître dans la liste.

Démarrez le service et vérifiez son fonctionnement

Si vous souhaitez exécuter le service, vous pouvez le démarrer à partir de l’écran de service ou à l’aide de la commande suivante.

sc start <サービス名>

La commande d’arrêt est la suivante.

sc stop <サービス名>

Si vous arrêtez le service, vous pouvez vérifier que le processus d’arrêt est en cours d’exécution.

Ajouter une description au service

Le champ de description du service ajouté est vide, mais vous pouvez l’ajouter à l’aide de la commande suivante.

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

Suppression d’un service

Si vous souhaitez supprimer le service, vous pouvez le faire à l’aide de la commande suivante. Vous devez disposer des privilèges d’administrateur à l’invite de commande.

sc delete <サービス名>