.NET 8'de Windows için hizmet oluşturma
Ç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 <サービス名>