.NET 8'de Windows için hizmet oluşturma

Sayfa güncel :
Sayfa oluşturma tarihi :

Çalışma ortamı

Görsel Stüdyo
  • Görsel Studio 2022
.NET
  • .NET 8
Windows
  • pencereler 11

Önkoşullar

Görsel Stüdyo
  • Görsel Studio 2022
.NET
  • .NET 8
Windows
  • pencereler 10
  • pencereler 11
Windows Sunucusu
  • Windows 2012 veya üzeri

önkoşul

  • Visual Studio zaten yüklü

İlk başta

Visual Studio .NET'te bir Windows hizmeti oluşturmaya çalıştığımda, yalnızca .NET Framework şablonları var. NET'te (Core) de oluşturulabilir ve şablon "Çalışan Hizmeti" olarak adlandırılır.

Bu yazıda, bir Windows hizmeti oluşturmak, kaydetmek ve çalıştırmak için bunun nasıl kullanılacağını açıklayacağım. İşleme içeriği minimum düzeydedir, bu nedenle bir Windows hizmeti olarak çalıştığını onaylayabiliyorsanız, lütfen işlevi oluşturun.

Proje oluşturma

Visual Studio'yu başlatın. Yeni proje oluştur'u seçin.

サービス Yukarıdaki arama alanına girin ve ardından listeden Çalışan Hizmeti'ni seçin. "Windows Hizmetleri", .NET sürümüne sahip olmayan .NET Framework sürümüdür.

Proje adı ve konumu isteğe bağlı olabilir. Kaydolduğunuz hizmeti etkilemez.

「. NET 8.0 seçilidir ve oluşturmak için varsayılanları bırakın.

Proje oluşturuldu.

Kitaplık Ekleme

İlk durumda, yalnızca bir "hizmet" işlevine sahiptir ve Windows'a özgü işlevleri yoktur. NuGet'ten bir Windows hizmeti tarafından kullanılabilecek bir kitaplık ekleyin.

Bağımlılıklar'a sağ tıklayın ve NuGet Paketlerini Yönet'i seçin.

Gözat sekmesini seçin ve arama alanına girin Microsoft.Extensions.Hosting.WindowsServices . Listede görünecektir, bu yüzden yükleyin.

Apply (Uygula) seçeneğini tıklayın.

Bir paket olarak eklendi.

Programları Düzenleme

Bu sefer, bir metin dosyasına Mr./Ms. olarak periyodik olarak metin ekleyen bir hizmet oluşturacağım.

Program.cs

Windows hizmetinin işlevselliğini aşağıdaki gibi ekleyin:

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

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

Worker.cs

Sınıf adını isteğe bağlı olarak değiştirebilirsiniz, ancak bu sefer varsayılanı bırakacağız.

Varsayılan olarak, yalnızca hizmet yürütüldüğünde işlenen yöntemler ExecuteAsync vardır, ancak bunu aşağıdaki gibi değiştirelim:

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

Yeni bir yöntem ve StopAsync yeni StartAsync bir yöntem ekledik. Adından da anlaşılacağı gibi, bu yöntemler hizmet başlatıldığında ve durdurulduğunda çağrılır. Sürecin içeriği sadece klasörler oluşturmak ve metin yazmaktır, bu yüzden açıklamayı atlayacağım.

ExecuteAsync Yöntem, iptal için işaretlenene kadar while stoppingToken ile döngüye devam eder. Hizmet çalışırken işlenmesini istediğiniz şeyi while ekleyin. Ancak, yalnızca taşımak istediğiniz işlemi yazarsanız, hizmet tam kapasite ile çalışacaktır, bu nedenle Task.Delay yöntem ile belirli bir süre beklerken taşımak temeldir. Varsayılan olarak, 1 saniyeye (1000ms) ayarlanmıştır, bu nedenle lütfen istediğiniz zaman yeniden yazın.

hata ayıklama

Visual Studio'dan hata ayıklayabilirsiniz. Hizmete gerçekten kayıtlı olmayacağınızdan emin olabilirsiniz.

Çalıştırdığınızda, konsol görünecektir.

İşlem doğruysa, dosyanın oluşturulduğunu görebilirsiniz.

Hata ayıklamayı durdurmak istiyorsanız konsolu kapatın.

Günlüğü kontrol ederseniz, hizmet başlatma işleminin geçtiğini, ancak sonlandırma işleminin geçmediğini görebilirsiniz. Sonlandırmayı görmek için, doğrulamak üzere Windows hizmetine gerçekten kaydolmanız gerekir.

sorun

Bir Windows hizmetine kaydolabilmek için programı yayımlamanız gerekir. Projeye sağ tıklayın ve Yayımla'yı seçin.

Klasörler'i seçin.

Klasör konumu varsayılan olarak güzeldir.

Yayınlama ayarları oluşturulacaktır, bu nedenle "Tüm Ayarları Göster" i seçin.

Aşağıdaki gibi ayarlayın:

Parametre Adı Değer Açıklamaları
konfigürasyon Serbest Bırak (varsayılan)
Hedef Çerçeve Net8.0 (varsayılan)
Dağıtım Modları Çerçeve Bağımlılığı Hizmet kayıt ortamı için ayrı ayrı. NEt 8 çalışma zamanını kuruyorsanız, bu ayar tamamdır.
Hedef Çalışma Zamanı win-x64 İşletim sistemi 32 bitlik bir ortamsa, win-x86'yı seçin
Hedef Konum temerrüt
Tek bir dosya oluşturma ÜZERİNDE
ReadyToRun Derlemesi keyfi

Ayarladıktan sonra, "Gönder" düğmesini tıklayın.

Sol alt köşede "Yayınlama başarılı oldu" mesajı görüntüleniyorsa işlem tamamlanmıştır.

Çıktı dosyası "Hedef Konum" tıklanarak açılabilir.

Programlara Yerleştirme ve Hizmetlere Kayıt

Windows hizmetini yönetici ayrıcalıklarıyla kaydetmek istediğiniz ortamda oturum açın.

Yayımlanan dosyayı, Windows hizmeti olarak kaydetmek istediğiniz ortama kopyalayın. Bunu herhangi bir klasöre yerleştirebilirsiniz, ancak Windows hizmetinin her zaman o klasördeki programa başvuracağını unutmayın.

Ayrıca, yayınlanan dosya uzantılı .pdb bir dosya içeriyorsa, geliştirme bilgileri içerdiğinden, belirtilmemiş bir kişi tarafından görülebileceği bir ortamda kopyalamayın.

Dosya yerleştirildikten sonra, bir Windows hizmeti olarak kaydedin. Kaydolmak için komutunu kullanın. Başlat menüsüne sağ tıklayın ve "Terminal (Yönetici)" seçeneğini seçin. Mr./Ms. bir Windows 11 ortamında çalışıyor, ancak diğer ortamlarda yönetici ayrıcalıklarına sahip bir komut istemi açmak sorun değil.

Terminal söz konusu olduğunda, önce PowerShell açık olabilir, ancak PowerShell bunu doğru şekilde ayarlayamayabilir, bu nedenle "Komut İstemi"ni açın.

Aşağıdaki komutla Windows hizmetine kaydedebilirsiniz:

biçim

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

Örnek Giriş

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

<サービス名> , Windows hizmetleri listesinde görünen addır. Ayrı bir görünen ad ayarlayabilirsiniz, ancak bir görünen ad belirtmezseniz, bu ad görüntülenir. Ayrıca kayıt defterini de etkiler, bu nedenle alfasayısal hizmet adları tercih edilir.

start=auto , Windows başlatıldığında hizmeti otomatik olarak başlatmak için kullanılan bir ayardır. El ile başlatmak istiyorsanız, bu açıklamayı silin.

binpath program dosyalarının tam yoludur.

Komutu yürütür ve [SC] CreateService SUCCESS görüntülerseniz, başarılı olur.

Kaydettiğiniz hizmetler listede görünmelidir.

Hizmeti başlatın ve çalışmasını kontrol edin

Servisi çalıştırmak istiyorsanız, servis ekranından veya aşağıdaki komut ile başlatabilirsiniz.

sc start <サービス名>

Durdur komutu aşağıdaki gibidir.

sc stop <サービス名>

Hizmeti durdurursanız, kapatma işleminin çalıştığını doğrulayabilirsiniz.

Hizmete açıklama ekleme

Eklenen servisin açıklama alanı boştur, ancak aşağıdaki komut ile ekleyebilirsiniz.

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

Bir Hizmeti Silme

Hizmeti silmek istiyorsanız, bunu aşağıdaki komutla yapabilirsiniz. Komut isteminde yönetici ayrıcalıklarına sahip olmanız gerekir.

sc delete <サービス名>