Cipta perkhidmatan untuk Windows dalam .NET 8

Laman dikemaskini :
Tarikh penciptaan halaman :

Persekitaran operasi

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

Prasyarat

Visual Studio
  • Visual Studio 2022
.BERSIH
  • .NET 8
Windows
  • Tingkap 10
  • Windows 11
Pelayan Windows
  • Windows 2012 atau lebih baru

prasyarat

  • Visual Studio telah dipasang

Pada mulanya

Apabila saya cuba membuat perkhidmatan Windows dalam Visual Studio .NET, hanya terdapat templat .NET Framework. Ia juga boleh dibuat dalam .NET (Teras), dan templat dinamakan "Perkhidmatan Pekerja".

Dalam artikel ini, saya akan menerangkan cara menggunakan ini untuk membuat, mendaftar dan menjalankan perkhidmatan Windows. Kandungan pemprosesan adalah minimum, jadi jika anda boleh mengesahkan bahawa ia berjalan sebagai perkhidmatan Windows, sila buat fungsi tersebut.

Buat projek

Mulakan Visual Studio. Pilih Cipta projek baharu.

Masukkan dalam サービス medan carian di atas, dan kemudian pilih Perkhidmatan Pekerja daripada senarai. "Perkhidmatan Windows" ialah versi .NET Framework, yang tidak mempunyai versi .NET.

Nama dan lokasi projek boleh sewenang-wenangnya. Ia tidak menjejaskan perkhidmatan yang anda daftarkan.

「. NET 8.0 dipilih dan biarkan lalai untuk menciptanya.

Projek ini telah diwujudkan.

Menambah Perpustakaan

Dalam keadaan awal, ia hanya mempunyai fungsi "perkhidmatan" dan tiada fungsi khusus Windows. Tambah pustaka yang boleh digunakan oleh perkhidmatan Windows daripada NuGet.

Klik kanan Kebergantungan dan pilih Urus Pakej NuGet.

Pilih tab Layari dan masukkan dalam Microsoft.Extensions.Hosting.WindowsServices medan carian. Ia akan muncul dalam senarai, jadi pasangkannya.

Klik Guna.

Ia telah ditambah sebagai pakej.

Program Penyuntingan

Kali ini, saya akan membuat perkhidmatan yang secara berkala menambah teks pada fail teks sebagai Mr./Cik.

Program.cs

Tambah kefungsian perkhidmatan Windows seperti berikut:

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

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

Worker.cs

Anda boleh menukar nama kelas sewenang-wenangnya, tetapi untuk kali ini kami akan meninggalkan lalai.

Secara lalai, hanya terdapat kaedah yang diproses ExecuteAsync apabila perkhidmatan dilaksanakan, tetapi mari kita ubahnya seperti berikut:

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

Kami telah menambah kaedah baharu dan StopAsync kaedah baharuStartAsync. Seperti namanya, kaedah ini dipanggil apabila perkhidmatan dimulakan dan apabila ia dihentikan. Kandungan proses ini hanyalah membuat folder dan menulis teks, jadi saya akan meninggalkan penjelasannya.

ExecuteAsync Kaedah ini terus bergelung dengan stoppingToken sehingga while ia dibenderakan untuk pembatalan. Tambah perkara yang while anda mahu diproses semasa perkhidmatan sedang berjalan. Walau bagaimanapun, jika anda hanya menulis proses yang ingin anda pindahkan, perkhidmatan akan berjalan pada kapasiti penuh, jadi Task.Delay adalah asas untuk memindahkannya sambil menunggu masa tertentu dengan kaedah tersebut. Secara lalai, ia ditetapkan kepada 1 saat (1000ms), jadi sila tulis semula pada bila-bila masa.

Nyahpepijat

Anda boleh nyahpepijat daripada Visual Studio. Yakinlah bahawa anda sebenarnya tidak akan berdaftar dengan perkhidmatan ini.

Apabila anda menjalankannya, konsol akan muncul.

Jika prosesnya betul, anda boleh melihat bahawa fail telah dibuat.

Jika anda ingin menghentikan penyahpepijatan, tutup konsol.

Jika anda menyemak log, anda dapat melihat bahawa proses permulaan perkhidmatan telah berlalu, tetapi proses penamatan belum. Untuk melihat penamatan, anda perlu benar-benar mendaftar dengan perkhidmatan Windows untuk mengesahkannya.

Isu

Untuk dapat mendaftar dengan perkhidmatan Windows, anda mesti menerbitkan program tersebut. Klik kanan projek dan pilih Terbitkan.

Pilih Folder.

Lokasi folder bagus secara lalai.

Tetapan penerbitan akan dibuat, jadi pilih "Tunjukkan Semua Tetapan".

Sediakan seperti berikut:

Parameter
Ucapan Nilai Nama
Konfigurasi Lepaskan (lalai)
Rangka Kerja Sasaran net8.0 (lalai)
Mod Penggunaan Pergantungan Rangka Kerja Secara berasingan untuk persekitaran pendaftaran perkhidmatan. Jika anda memasang masa jalan NEt 8, tetapan ini OK.
Masa Jalanan Sasaran menang-x64 Jika OS ialah persekitaran 32-bit, pilih win-x86
Lokasi Sasaran Lalai
Mencipta fail tunggal PADA
Kompilasi ReadyToRun Sewenang

Selepas menetapkan, klik butang "Serah".

Jika "Penerbitan berjaya" dipaparkan di penjuru kiri bawah, ia telah selesai.

Fail output boleh dibuka dengan mengklik "Lokasi Sasaran".

Penempatan Program dan Pendaftaran dalam Perkhidmatan

Log masuk ke persekitaran di mana anda ingin mendaftarkan perkhidmatan Windows dengan keistimewaan pentadbir.

Salin fail yang diterbitkan ke persekitaran di mana anda ingin mendaftarkannya sebagai perkhidmatan Windows. Anda boleh meletakkannya dalam mana-mana folder, tetapi perlu diingat bahawa perkhidmatan Windows akan sentiasa merujuk kepada program dalam folder itu.

Juga, jika fail yang diterbitkan mengandungi fail dengan sambungan .pdb , jangan salinannya dalam persekitaran di mana ia boleh dilihat oleh orang yang tidak ditentukan kerana ia mengandungi maklumat pembangunan.

Setelah fail disediakan, daftarkannya sebagai perkhidmatan Windows. Gunakan arahan untuk mendaftar. Klik kanan pada menu Mula dan pilih "Terminal (Pentadbir)". Mr./Ms. berjalan dalam persekitaran Windows 11, tetapi dalam persekitaran lain, tidak mengapa untuk membuka gesaan arahan dengan keistimewaan pentadbir.

Dalam kes terminal, PowerShell mungkin dibuka terlebih dahulu, tetapi PowerShell mungkin tidak dapat menyediakannya dengan betul, jadi buka "Command Prompt".

Anda boleh mendaftarkannya dengan perkhidmatan Windows dengan arahan berikut:

Format

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

Contoh Input

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

<サービス名> ialah nama yang muncul dalam senarai perkhidmatan Windows. Anda boleh menetapkan nama paparan yang berasingan, tetapi jika anda tidak menentukan nama paparan, nama ini akan dipaparkan. Ia juga menjejaskan pendaftaran, jadi nama perkhidmatan abjad angka lebih diutamakan.

start=auto ialah tetapan untuk memulakan perkhidmatan secara automatik apabila Windows bermula. Jika anda ingin memulakannya secara manual, padamkan penerangan ini.

binpath ialah laluan penuh fail program.

Jika anda melaksanakan arahan dan [SC] CreateService SUCCESS memaparkan , ia berjaya.

Perkhidmatan yang anda daftarkan akan muncul dalam senarai.

Mulakan perkhidmatan dan periksa operasinya

Jika anda ingin menjalankan perkhidmatan, anda boleh memulakannya dari skrin perkhidmatan atau dengan arahan berikut.

sc start <サービス名>

Perintah berhenti adalah seperti berikut.

sc stop <サービス名>

Jika anda menghentikan perkhidmatan, anda boleh mengesahkan bahawa proses penutupan sedang berjalan.

Tambah perihalan pada perkhidmatan

Medan perihalan perkhidmatan tambahan adalah kosong, tetapi anda boleh menambahnya dengan arahan berikut.

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

Memadamkan Perkhidmatan

Jika anda ingin memadamkan perkhidmatan, anda boleh berbuat demikian dengan arahan berikut. Anda mesti mempunyai keistimewaan pentadbir pada prompt arahan.

sc delete <サービス名>