kullanarak bir Windows hizmeti oluşturmaBackgroundService
.NET Framework geliştiriciler, Windows hizmeti uygulamalarıyla tanıdık olabilir. .net Core ve .net 5 + öncesinde, .NET Framework 'e bağlı olan geliştiriciler arka plan görevleri gerçekleştirmek veya uzun süreli işlemleri yürütmek için Windows hizmetleri oluşturabilir. bu işlevsellik hala kullanılabilir ve bir Windows hizmeti olarak çalışan çalışan hizmetleri oluşturabilirsiniz.
Bu öğreticide aşağıdakilerin nasıl yapılacağını öğreneceksiniz:
- .NET Worker uygulamasını tek bir dosya yürütülebilir dosyası olarak yayımlayın.
- Windows bir hizmet oluşturun.
BackgroundServiceuygulamayı bir Windows hizmeti olarak oluşturun.- Windows hizmeti 'ni başlatın ve durdurun.
- Olay günlüklerini görüntüleyin.
- Windows hizmetini silin.
İpucu
".NET 'teki çalışanlar" örnek kaynak kodu, indirmek üzere Samples Browser 'da bulunabilir. Daha fazla bilgi için bkz. kod örneklerine gözatıyor: .net Içindeki çalışanlar.
Önkoşullar
- .Net 5,0 SDK veya üzeri
- Windows Işletim sistemi
- .NET tümleşik geliştirme ortamı (IDE)
- Visual Studio kullanmayı ücretsiz yapın
Yeni proje oluşturma
Yeni bir Çalışan Hizmeti projesi oluşturmak Visual Studio Dosya Yeni Proje... seçeneğini > > belirtirsiniz. Yeni proje oluştur iletişim kutusunda "Çalışan Hizmeti" araması yazın ve Çalışan Hizmeti şablonunu seçin. .NET CLI kullanmak yerine sık kullanılan terminali bir çalışma dizininde açın. komutunu dotnet new çalıştırın ve yerine <Project.Name> istediğiniz proje adını yazın.
dotnet new worker --name <Project.Name>
.NET CLI yeni çalışan hizmeti projesi komutu hakkında daha fazla bilgi için bkz. dotnet new worker.
İpucu
Visual Studio Code kullanıyorsanız tümleşik terminalden .NET CLI komutlarını çalıştırabilirsiniz. Daha fazla bilgi için bkz. Visual Studio Code: Tümleşik Terminal.
NuGet paketi 'ni yükler
.net uygulamalarından yerel Windows hizmetleriyle birlikte çalışabilmek için IHostedService Microsoft.Extensions.Hosting.WindowsServices NuGet paketiniyüklemeniz gerekir.
bunu Visual Studio yüklemek için, NuGet paketlerini yönet... iletişim kutusunu kullanın. "Microsoft. Extensions. Hosting. WindowsServices" ifadesini arayın ve bu dosyayı yükler. .NET CLı 'yı kullanmayı tercih ediyorsanız, şu dotnet add package komutu çalıştırın:
dotnet add package Microsoft.Extensions.Hosting.WindowsServices
bu öğreticinin örnek kaynak kodunun bir parçası olarak, Microsoft.Extensions.Http NuGet paketinide yüklemeniz gerekir.
dotnet add package Microsoft.Extensions.Http
.NET CLı Add Package komutu hakkında daha fazla bilgi için bkz dotnet add package ..
Paketler başarıyla eklendikten sonra, proje dosyanızda aşağıdaki paket başvuruları bulunmalıdır:
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
</ItemGroup>
Proje dosyasını güncelleştir
Bu çalışan proje, C# ' nin null yapılabilir başvuru türlerinikullanımını sağlar. Tüm projeyi etkinleştirmek için proje dosyasını uygun şekilde güncelleştirin:
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<RootNamespace>App.WindowsService</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
</ItemGroup>
</Project>
Önceki proje dosyası değişiklikleri <Nullable>enable<Nullable> düğümü ekler. Daha fazla bilgi için bkz. Nullable bağlamı ayarlama.
Hizmeti oluşturma
Jokeservice. cs adlı projeye yeni bir sınıf ekleyin ve Içeriğini aşağıdaki C# koduyla değiştirin:
using System.Net.Http.Json;
using System.Text.Json;
namespace App.WindowsService;
public class JokeService
{
private readonly HttpClient _httpClient;
private readonly JsonSerializerOptions _options = new()
{
PropertyNameCaseInsensitive = true
};
private const string JokeApiUrl =
"https://karljoke.herokuapp.com/jokes/programming/random";
public JokeService(HttpClient httpClient) => _httpClient = httpClient;
public async Task<string> GetJokeAsync()
{
try
{
// The API returns an array with a single entry.
Joke[]? jokes = await _httpClient.GetFromJsonAsync<Joke[]>(
JokeApiUrl, _options);
Joke? joke = jokes?[0];
return joke is not null
? $"{joke.Setup}{Environment.NewLine}{joke.Punchline}"
: "No joke here...";
}
catch (Exception ex)
{
return $"That's not funny! {ex}";
}
}
}
public record Joke(int Id, string Type, string Setup, string Punchline);
Önceki şaka hizmeti kaynak kodu, yöntemi tek bir işlev gösterir GetJokeAsync . Bu, Task<TResult> T bir olan string ve rastgele programlama şaka temsil eden bir döndüren yöntemdir. HttpClientOluşturucuya eklenir ve sınıf kapsamı _httpClient değişkenine atanır.
İpucu
Şaka API 'SI GitHub açık kaynaklı bir projem. Bu, tanıtım amacıyla kullanılır ve gelecekte kullanılabilir olacağını garanti etmez. API 'yi hızlı bir şekilde test etmek için aşağıdaki URL 'YI bir tarayıcıda açın:
https://karljoke.herokuapp.com/jokes/programming/random.
Sınıfı yeniden yazın Worker
WorkerŞablondan varolanı aşağıdaki C# koduyla değiştirin ve dosyayı Windowsbackgroundservice. cs olarak yeniden adlandırın:
namespace App.WindowsService;
public sealed class WindowsBackgroundService : BackgroundService
{
private readonly JokeService _jokeService;
private readonly ILogger<WindowsBackgroundService> _logger;
public WindowsBackgroundService(
JokeService jokeService,
ILogger<WindowsBackgroundService> logger) =>
(_jokeService, _logger) = (jokeService, logger);
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
string joke = await _jokeService.GetJokeAsync();
_logger.LogWarning(joke);
await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
}
}
}
Önceki kodda, JokeService bir ile birlikte eklenir ILogger . Her ikisi de alan olarak sınıf için kullanılabilir hale getirilir private readonly . ExecuteAsyncYönteminde, şaka hizmeti bir şaka ister ve bunu günlükçü öğesine yazar. bu durumda, günlükçü Windows olay günlüğü tarafından uygulanır Microsoft.Extensions.Logging.EventLog.EventLogLogger . Günlükler öğesine yazılır ve Olay Görüntüleyicisi görüntülenmek üzere kullanılabilir.
Not
Varsayılan olarak, olay günlüğü önem derecesi ' dir Warning . Bu yapılandırılabilir, ancak tanıtım amacıyla WindowsBackgroundService LogWarning uzantı yöntemiyle Günlükler için. Düzeyi özellikle hedeflemek için EventLog appSettings 'e bir giriş ekleyin . { Environment}. JSON veya bir değer sağlayın EventLogSettings.Filter .
"Logging": {
"EventLog": {
"LogLevel": {
"Default": "Information"
}
}
}
günlük düzeylerini yapılandırma hakkında daha fazla bilgi için bkz. .net 'te günlüğe kaydetme sağlayıcıları: Configure Windows EventLog.
Sınıfı yeniden yazın Program
Şablon programı. cs dosya Içeriğini aşağıdaki C# koduyla değiştirin:
using App.WindowsService;
using IHost host = Host.CreateDefaultBuilder(args)
.UseWindowsService(options =>
{
options.ServiceName = ".NET Joke Service";
})
.ConfigureServices(services =>
{
services.AddHostedService<WindowsBackgroundService>();
services.AddHttpClient<JokeService>();
})
.Build();
await host.RunAsync();
UseWindowsServicegenişletme yöntemi, uygulamayı bir Windows hizmeti olarak çalışacak şekilde yapılandırır. Hizmet adı olarak ayarlanır ".NET Joke Service" . Barındırılan hizmet kaydedilir ve HttpClient JokeService bağımlılık ekleme için öğesine kaydedilir.
Hizmetleri kaydetme hakkında daha fazla bilgi için bkz. .net 'Te bağımlılık ekleme.
Uygulamayı yayımlama
.net Worker hizmeti uygulamasını Windows bir hizmet olarak oluşturmak için, uygulamayı tek bir dosya yürütülebilir dosyası olarak yayımlamanız önerilir. Dosya sistemi etrafında herhangi bir bağımlı dosya olmadığından, kendi kendine dahil olan bir yürütülebilir dosya olması daha az hataya açıktır. ancak, Windows hizmeti denetim yöneticisi tarafından hedeflenebilir bir * .exe dosyası oluştururken, bu, tam olarak kabul edilebilir olan farklı bir yayımlama modülebilirliği seçebilirsiniz.
Önemli
alternatif bir yayımlama yaklaşımı, * .dll ( * .exe yerine) oluşturmak ve yayımlanan uygulamayı Windows hizmet denetimi yöneticisi 'ni kullanarak yüklediğinizde, .net clı 'ye temsilciliğini ve DLL 'yi geçitirsiniz. Daha fazla bilgi için bkz. .net CLI: DotNet komutu.
sc.exe create ".NET Joke Service" binpath="C:\Path\To\dotnet.exe C:\Path\To\App.WindowsService.dll"
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>true</ImplicitUsings>
<RootNamespace>App.WindowsService</RootNamespace>
<OutputType>exe</OutputType>
<PublishSingleFile>true</PublishSingleFile>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="6.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
</ItemGroup>
</Project>
Proje dosyasının önceki vurgulanmış satırları aşağıdaki davranışları tanımlar:
<OutputType>exe</OutputType>: Bir konsol uygulaması oluşturur.<PublishSingleFile>true</PublishSingleFile>: Tek dosya yayımlamayı mümkün.<RuntimeIdentifier>win-x64</RuntimeIdentifier>: RID 'sini belirtirwin-x64.<PlatformTarget>x64</PlatformTarget>: Hedef platform CPU 'SU olan 64-bit ' i belirtin.
uygulamayı Visual Studio yayımlamak için, kalıcı olan bir yayımlama profili oluşturabilirsiniz. Yayımlama profili XML tabanlıdır ve . pubxml dosya uzantısına sahiptir. Visual Studio uygulamayı örtük olarak yayımlamak için bu profili kullanır, ancak .net clı kullanıyorsanız, — kullanılacak yayımlama profilini açıkça belirtmeniz gerekir.
Çözüm Gezgini projeye sağ tıklayın ve Yayımla...' yı seçin. Ardından profil oluşturmak için bir yayımlama profili Ekle ' yi seçin. Yayımla Iletişim kutusunda hedef olarak klasör ' ü seçin.
Varsayılan konumu bırakın ve son' u seçin. Profil oluşturulduktan sonra tüm ayarları göster' i seçin ve profil ayarlarınızı doğrulayın.
Aşağıdaki ayarların belirtildiğinden emin olun:
- Dağıtım modu: kendinden bağımsız
- Tek dosya üret: işaretlendi
- ReadyToRun derlemesini etkinleştir: işaretlendi
- Kullanılmayan derlemeleri Kırp (önizlemede): işaretlenmemiş
Son olarak Yayımla' yı seçin. Uygulama derlenir ve elde edilen .exe dosyası /Publish çıkış dizinine yayımlanır.
Alternatif olarak, uygulamayı yayımlamak için .NET CLı kullanabilirsiniz:
dotnet publish --output "C:\custom\publish\directory"
Daha fazla bilgi için bkz. dotnet publish.
Windows hizmetini oluşturma
Windows hizmeti oluşturmak için yerel Windows Service Control Manager 'ın (sc.exe) create komutunu kullanın. PowerShell’i Yönetici olarak çalıştırın.
sc.exe create ".NET Joke Service" binpath="C:\Path\To\App.WindowsService.exe"
İpucu
Konak yapılandırmasınıniçerik kökünü değiştirmeniz gerekiyorsa, şunu belirtirken bir komut satırı bağımsız değişkeni olarak geçirebilirsiniz binpath :
sc.exe create "Svc Name" binpath="C:\Path\To\App.exe --contentRoot C:\Other\Path"
Bir çıkış iletisi görürsünüz:
[SC] CreateService SUCCESS
Daha fazla bilgi için bkz. sc.exe oluşturma.
Windows hizmetini yapılandırma
Hizmet oluşturulduktan sonra, isteğe bağlı olarak yapılandırabilirsiniz. Hizmet varsayılanlarıyla ilgili bir sorun yaşıyorsanız, hizmet Işlevlerini doğrula bölümüne atlayın.
Windows hizmetleri kurtarma yapılandırma seçeneklerini sağlar. Geçerli yapılandırma sc.exe qfailure "<Service Name>" <Service Name> değerlerini okumak için (hizmetlerinizin ' adınız) komutunu kullanarak geçerli yapılandırmayı sorgulayabilirsiniz:
sc qfailure ".NET Joke Service"
[SC] QueryServiceConfig2 SUCCESS
SERVICE_NAME: .NET Joke Service
RESET_PERIOD (in seconds) : 0
REBOOT_MESSAGE :
COMMAND_LINE :
Bu komut, — henüz yapılandırılmadıklarından bu yana varsayılan değerler olan kurtarma yapılandırması çıktısını alırlar.
Kurtarmayı yapılandırmak için, sc.exe failure "<Service Name>" hizmetinizin adı olduğu yeri kullanın <Service Name> :
sc.exe failure ".NET Joke Service" reset=0 actions=restart/60000/restart/60000/run/1000
[SC] ChangeServiceConfig2 SUCCESS
İpucu
Kurtarma seçeneklerini yapılandırmak için, Terminal oturumunuzun yönetici olarak çalıştırılması gerekir.
Başarıyla yapılandırıldığında, komutunu kullanarak değerleri bir kez daha sc.exe qfailure "<Service Name>" sorguabilirsiniz:
sc qfailure ".NET Joke Service"
[SC] QueryServiceConfig2 SUCCESS
SERVICE_NAME: .NET Joke Service
RESET_PERIOD (in seconds) : 0
REBOOT_MESSAGE :
COMMAND_LINE :
FAILURE_ACTIONS : RESTART -- Delay = 60000 milliseconds.
RESTART -- Delay = 60000 milliseconds.
RUN PROCESS -- Delay = 1000 milliseconds.
Yapılandırılan yeniden başlatma değerlerini görüyorsunuz.
Hizmet işlevselliğini doğrulama
Windows Hizmeti olarak oluşturulan uygulamayı görmek için Hizmetler'i açın. Üst Windows (veya Ctrl + Esc)seçin ve "Hizmetler" içinde arama. Hizmetler uygulamasından hizmetinizi adıyla bulabilirsiniz.
Hizmetin beklendiği gibi çalıştığını doğrulamak için şunları yapmak gerekir:
- Hizmeti başlatma
- Günlükleri görüntüleme
- Hizmeti durdurma
Önemli
Uygulamada hata ayıklamak için, Windows Services işlemi içinde etkin olarak çalışan yürütülebilir dosyada hata ayıklamaya çalışmayabilirsiniz.
Windows Hizmetini başlatma
Windows Service'i başlatmak için şu komutu sc.exe start kullanın:
sc.exe start ".NET Joke Service"
Aşağıdakine benzer bir çıktıyı görüyorsunuz:
SERVICE_NAME: .NET Joke Service
TYPE : 10 WIN32_OWN_PROCESS
STATE : 2 START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x7d0
PID : 37636
FLAGS
Hizmet Durumu, 'den START_PENDING Çalışıyor'a geçiştir.
Günlükleri görüntüleme
Günlükleri görüntülemek için Olay Görüntüleyicisi. Üst Windows (veya Ctrl + Esc)seçin ve ifadesini arayın. "Event Viewer" Günlükler Olay Görüntüleyicisi düğümünü Windows > (Yerel) > seçeneğini seçin. Uygulama ad alanıyla eşleşen bir Kaynak ile Uyarı düzeyi girişi görüyor olun. Girişe çift tıklayın veya sağ tıklar ve Olay Özellikleri'ne tıklar ve ayrıntıları görüntüler.
Günlükleri Olay Günlüğünde gördükten sonra hizmeti durdurmanız gerekir. Dakikada bir rastgele rastgele bir günlük kaydı yapmak için tasarlanmıştır. Bu kasıtlı bir davranıştır ancak üretim hizmetleri için pratik değildir.
Windows Hizmetini durdurma
Windows Service'i durdurmak için şu komutu sc.exe stop kullanın:
sc.exe stop ".NET Joke Service"
Aşağıdakine benzer bir çıktıyı görüyorsunuz:
SERVICE_NAME: .NET Joke Service
TYPE : 10 WIN32_OWN_PROCESS
STATE : 3 STOP_PENDING
(STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
Hizmet Durumu, 'den STOP_PENDING Durduruldu'ya geçiştir.
Windows Service'i silme
Windows Service'i silmek için yerel Windows Service Control Manager'ın (sc.exe) delete komutunu kullanın. PowerShell’i Yönetici olarak çalıştırın.
Önemli
Hizmet Durduruldu durumda değilse hemen silinmez. Delete komutunu vermeden önce hizmetin durdurulmuş olduğundan emin olmak.
sc.exe delete ".NET Joke Service"
Bir çıkış iletisi alırsınız:
[SC] DeleteService SUCCESS
Daha fazla bilgi için bkz.sc.exe silme.