Crearea unui serviciu pentru Windows în .NET 8

Pagina actualizată :
Data creării paginii :

Mediu de operare

Visual Studio
  • Visual Studio 2022
.NET
  • .NET 8
Windows
  • Ferestre 11

Cerințe preliminare

Visual Studio
  • Visual Studio 2022
.NET
  • .NET 8
Windows
  • Ferestre 10
  • Ferestre 11
Windows Server
  • Windows 2012 sau o versiune ulterioară

Condiție prealabilă

  • Visual Studio este deja instalat

La început

Când încerc să creez un serviciu Windows în Visual Studio .NET, există numai șabloane .NET Framework. De asemenea, poate fi creat în .NET (Core), iar șablonul se numește "Worker Service".

În acest articol, vă voi explica cum să utilizați acest lucru pentru a crea, înregistra și rula un serviciu Windows. Conținutul de procesare este minim, deci dacă puteți confirma că rulează ca un serviciu Windows, vă rugăm să creați funcția.

Crearea unui proiect

Porniți Visual Studio. Selectați Creați un proiect nou.

Introduceți în câmpul de căutare de サービス mai sus, apoi selectați Worker Service din listă. "Windows Services" este versiunea .NET Framework, care nu are o versiune .NET.

Numele și locația proiectului pot fi arbitrare. Nu afectează serviciul la care vă înregistrați.

「. NET 8.0 este selectat și lăsați valorile implicite pentru ao crea.

Proiectul a fost creat.

Adăugarea bibliotecilor

În starea inițială, are doar o funcție "service" și nu are funcții specifice Windows. Adăugați o bibliotecă care poate fi utilizată de un serviciu Windows de la NuGet.

Faceți clic dreapta pe Dependențe și selectați Gestionare pachete NuGet.

Selectați fila Răsfoire și introduceți în câmpul de Microsoft.Extensions.Hosting.WindowsServices căutare. Acesta va apărea în listă, deci instalați-l.

Dați clic pe Aplicați.

A fost adăugat ca pachet.

Editarea programelor

De data aceasta, voi crea un serviciu care adaugă periodic text la un fișier text ca domn / doamnă.

Program.cs

Adăugați funcționalitatea serviciului Windows după cum urmează:

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

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

Worker.cs

Puteți schimba numele clasei în mod arbitrar, dar pentru acest timp vom lăsa implicit.

În mod implicit, există numai metode care sunt ExecuteAsync procesate atunci când serviciul este executat, dar să îl modificăm după cum urmează:

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

Am adăugat o nouă metodă și StopAsync o nouă StartAsync metodă. După cum sugerează și numele, aceste metode sunt apelate atunci când serviciul este pornit și când este oprit. Conținutul procesului este pur și simplu crearea de foldere și scrierea textului, așa că voi omite explicația.

ExecuteAsync Metoda continuă să se repete cu stopToken până când while este semnalizată pentru anulare. Adăugați ceea ce while doriți să fie procesat în timp ce serviciul rulează. Cu toate acestea, dacă scrieți doar procesul pe care doriți să îl mutați, serviciul va rula la capacitate maximă, deci Task.Delay este de bază să îl mutați în timp ce așteptați un anumit timp cu metoda. În mod implicit, este setat la 1 secundă (1000ms), așa că vă rugăm să îl rescrieți oricând.

Depanare

Puteți depana din Visual Studio. Fiți siguri că nu veți fi de fapt înregistrat la serviciu.

Când o rulați, va apărea consola.

Dacă procesul este corect, puteți vedea că fișierul a fost creat.

Dacă doriți să opriți depanarea, închideți consola.

Dacă verificați jurnalul, puteți vedea că procesul de pornire a serviciului a trecut, dar procesul de terminare nu. Pentru a vedea rezilierea, trebuie să vă înregistrați efectiv la serviciul Windows pentru a o verifica.

problemă

Pentru a vă putea înregistra la un serviciu Windows, trebuie să publicați programul. Faceți clic dreapta pe proiect și alegeți Publicare.

Selectați Foldere.

Locația folderului este plăcută în mod implicit.

Setările de publicare vor fi create, deci selectați "Afișați toate setările".

Configurați-l după cum urmează:

Nume parametru Observații valoare
configurație Versiune (implicit)
Cadrul țintă net8.0 (implicit)
Moduri de implementare Dependența cadrului Separat pentru mediul de înregistrare a serviciilor. Dacă instalați NEt 8 runtime, această setare este OK.
Timp de rulare țintă câștig-x64 Dacă sistemul de operare este un mediu pe 32 de biți, selectați win-x86
Locație țintă Implicit
Crearea unui singur fișier PE
Compilație ReadyToRun arbitrar

După setare, faceți clic pe butonul "Trimiteți".

Dacă "Publicarea a reușit" este afișată în colțul din stânga jos, aceasta este finalizată.

Fișierul de ieșire poate fi deschis făcând clic pe "Locație țintă".

Plasarea programului și înscrierea în servicii

Conectați-vă la mediul în care doriți să înregistrați serviciul Windows cu privilegii de administrator.

Copiați fișierul publicat în mediul în care doriți să îl înregistrați ca serviciu Windows. Îl puteți plasa în orice folder, dar rețineți că serviciul Windows se va referi întotdeauna la programul din acel folder.

De asemenea, dacă fișierul publicat conține un fișier cu extensia .pdb , nu îl copiați într-un mediu în care poate fi văzut de o persoană nespecificată, deoarece conține informații despre dezvoltare.

Odată ce fișierul este în loc, înregistrați-l ca serviciu Windows. Utilizați comanda pentru a vă înregistra. Faceți clic dreapta pe meniul Start și selectați "Terminal (Admin)". Mr./Ms. rulează într-un mediu Windows 11, dar în alte medii, este OK să deschideți un prompt de comandă cu privilegii de administrator.

În cazul terminalului, PowerShell poate fi deschis mai întâi, dar este posibil ca PowerShell să nu îl poată configura corect, deci deschideți "Command Prompt".

Îl puteți înregistra la serviciul Windows cu următoarea comandă:

format

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

Exemplu de intrare

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

<サービス名> este numele care apare în lista de servicii Windows. Puteți seta un nume afișat separat, dar dacă nu specificați un nume afișat, acest nume va fi afișat. De asemenea, afectează registrul, astfel încât sunt preferate nume de servicii alfanumerice.

start=auto este o setare pentru pornirea automată a serviciului la pornirea Windows. Dacă doriți să o porniți manual, ștergeți această descriere.

binpath este calea completă a fișierelor programului.

Dacă executați comanda și [SC] CreateService SUCCESS afișați , are succes.

Serviciile pe care le-ați înregistrat ar trebui să apară în listă.

Porniți serviciul și verificați funcționarea acestuia

Dacă doriți să rulați serviciul, îl puteți porni din ecranul de service sau cu următoarea comandă.

sc start <サービス名>

Comanda de oprire este după cum urmează.

sc stop <サービス名>

Dacă opriți serviciul, puteți verifica dacă se execută procesul de închidere.

Adăugați o descriere la serviciu

Câmpul de descriere al serviciului adăugat este necompletat, dar îl puteți adăuga cu următoarea comandă.

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

Ștergerea unui serviciu

Dacă doriți să ștergeți serviciul, puteți face acest lucru cu următoarea comandă. Trebuie să aveți privilegii de administrator la promptul de comandă.

sc delete <サービス名>