Creare un servizio per Windows in .NET 8

Pagina aggiornata :
Data di creazione della pagina :

Ambiente operativo

Studio visivo
  • Studio visivo 2022
.RETE
  • .NET 8
Finestre
  • finestre 11

Prerequisiti

Studio visivo
  • Studio visivo 2022
.RETE
  • .NET 8
Finestre
  • finestre 10
  • finestre 11
Windows Server
  • Windows 2012 o versioni successive

precondizione

  • Visual Studio è già installato

Dapprima

Quando si tenta di creare un servizio Windows in Visual Studio .NET, sono presenti solo modelli .NET Framework. Può anche essere creato in .NET (Core) e il modello è denominato "Servizio di lavoro".

In questo articolo, spiegherò come utilizzare questo per creare, registrare ed eseguire un servizio Windows. Il contenuto dell'elaborazione è minimo, quindi se è possibile confermare che è in esecuzione come servizio Windows, creare la funzione.

Creare un progetto

Avviare Visual Studio. Seleziona Crea un nuovo progetto.

Immettere nel campo di サービス ricerca in alto, quindi selezionare Servizio lavoratore dall'elenco. "Servizi Windows" è la versione di .NET Framework, che non dispone di una versione di .NET.

Il nome e la posizione del progetto possono essere arbitrari. Non influisce sul servizio a cui ti stai registrando.

「. NET 8.0 è selezionata e lasciare le impostazioni predefinite per crearlo.

Il progetto è stato creato.

Aggiunta di librerie

Nello stato iniziale, ha solo una funzione di "servizio" e nessuna funzione specifica di Windows. Aggiungere una libreria che può essere usata da un servizio Windows da NuGet.

Fare clic con il pulsante destro del mouse su Dipendenze e scegliere Gestisci pacchetti NuGet.

Seleziona la scheda Sfoglia e inserisci nel campo di Microsoft.Extensions.Hosting.WindowsServices ricerca. Apparirà nell'elenco, quindi installalo.

Fare clic su Applica.

È stato aggiunto come pacchetto.

Programmi di editing

Questa volta, creerò un servizio che aggiunge periodicamente testo a un file di testo come Sig./Sig..

Program.cs

Aggiungere la funzionalità del servizio Windows come indicato di seguito:

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

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

Worker.cs

È possibile modificare il nome della classe in modo arbitrario, ma per questa volta lasceremo l'impostazione predefinita.

Per impostazione predefinita, ci sono solo metodi che vengono ExecuteAsync elaborati quando il servizio viene eseguito, ma cambiamolo come segue:

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

Abbiamo aggiunto un nuovo metodo e StopAsync un nuovo StartAsync metodo. Come suggerisce il nome, questi metodi vengono chiamati all'avvio e all'arresto del servizio. Il contenuto del processo consiste semplicemente nella creazione di cartelle e nella scrittura del testo, quindi ometterò la spiegazione.

ExecuteAsync Il metodo continua a eseguire il ciclo con stoppingToken fino a quando non while viene contrassegnato per l'annullamento. Aggiungere ciò che while si desidera venga elaborato mentre il servizio è in esecuzione. Tuttavia, se si scrive solo il processo che si desidera spostare, il servizio verrà eseguito a piena capacità, quindi Task.Delay è fondamentale spostarlo in attesa di un certo tempo con il metodo. Per impostazione predefinita, è impostato su 1 secondo (1000 ms), quindi riscrivilo in qualsiasi momento.

Eseguire il debug

È possibile eseguire il debug da Visual Studio. Stai certo che non sarai effettivamente registrato al servizio.

Quando lo esegui, apparirà la console.

Se il processo è corretto, puoi vedere che il file è stato creato.

Se si desidera interrompere il debug, chiudere la console.

Se si controlla il registro, è possibile notare che il processo di avvio del servizio è stato superato, ma il processo di terminazione no. Per visualizzare la terminazione, è necessario registrarsi effettivamente con il servizio Windows per verificarla.

questione

Per potersi registrare con un servizio Windows, è necessario pubblicare il programma. Fare clic con il pulsante destro del mouse sul progetto e scegliere Pubblica.

Seleziona Cartelle.

La posizione della cartella è buona per impostazione predefinita.

Verranno create le impostazioni di pubblicazione, quindi seleziona "Mostra tutte le impostazioni".

Configuralo come segue:

Note valore
sul del nome del parametro
configurazione Rilascio (impostazione predefinita)
Framework di destinazione net8.0 (impostazione predefinita)
Modalità di distribuzione Dipendenza del framework Separatamente per l'ambiente di registrazione del servizio. Se si sta installando il runtime NEt 8, questa impostazione è OK.
Runtime di destinazione vinci-x64 Se il sistema operativo è un ambiente a 32 bit, selezionare win-x86
Posizione di destinazione default
Creazione di un singolo file SU
Compilazione ReadyToRun arbitrario

Dopo l'impostazione, fare clic sul pulsante "Invia".

Se nell'angolo in basso a sinistra viene visualizzato il messaggio "Pubblicazione riuscita", significa che l'operazione è completa.

Il file di output può essere aperto facendo clic su "Posizione di destinazione".

Collocamento del programma e iscrizione ai servizi

Accedere all'ambiente in cui si desidera registrare il servizio Windows con privilegi di amministratore.

Copiare il file pubblicato nell'ambiente in cui si desidera registrarlo come servizio Windows. Puoi inserirlo in qualsiasi cartella, ma tieni presente che il servizio Windows farà sempre riferimento al programma in quella cartella.

Inoltre, se il file pubblicato contiene un file con estensione .pdb , non copiarlo in un ambiente in cui può essere visto da una persona non specificata perché contiene informazioni sullo sviluppo.

Una volta che il file è stato posizionato, registrarlo come servizio Windows. Utilizzare il comando per registrarsi. Fare clic con il pulsante destro del mouse sul menu Start e selezionare "Terminale (amministratore)". Mr./Ms. è in esecuzione in un ambiente Windows 11, ma in altri ambienti è possibile aprire un prompt dei comandi con privilegi di amministratore.

Nel caso del terminale, PowerShell potrebbe essere aperto per primo, ma PowerShell potrebbe non essere in grado di configurarlo correttamente, quindi apri il "Prompt dei comandi".

È possibile registrarlo con il servizio Windows con il seguente comando:

formato

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

Input di esempio

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

<サービス名> è il nome che appare nell'elenco dei servizi di Windows. È possibile impostare un nome visualizzato separato, ma se non si specifica un nome visualizzato, verrà visualizzato questo nome. Influisce anche sul Registro di sistema, quindi sono preferiti i nomi dei servizi alfanumerici.

start=auto è un'impostazione per avviare automaticamente il servizio all'avvio di Windows. Se si desidera avviarlo manualmente, eliminare questa descrizione.

binpath è il percorso completo dei file di programma.

Se si esegue il comando e [SC] CreateService SUCCESS si visualizza , l'operazione ha esito positivo.

I servizi registrati dovrebbero apparire nell'elenco.

Avviare il servizio e verificarne il funzionamento

Se si desidera eseguire il servizio, è possibile avviarlo dalla schermata del servizio o con il seguente comando.

sc start <サービス名>

Il comando stop è il seguente.

sc stop <サービス名>

Se si arresta il servizio, è possibile verificare che il processo di arresto sia in esecuzione.

Aggiungere una descrizione al servizio

Il campo della descrizione del servizio aggiunto è vuoto, ma è possibile aggiungerlo con il comando seguente.

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

Eliminazione di un servizio

Se si desidera eliminare il servizio, è possibile farlo con il seguente comando. È necessario disporre dei privilegi di amministratore al prompt dei comandi.

sc delete <サービス名>