Create a windows service with .NET

Command line

Please refer to my previous article of how to create a service with the topshelf library: https://alexrait.blogspot.com/2023/03/running-topshelf-with-quartz-in-net.html.

This time here is the most simple way of creating a windows service with .NET 8 with no dependency on topshelf. First, install these packages with nuget:

  • Microsoft.Extensions.Hosting
  • Microsoft.Extensions.Hosting.Abstractions

Create a background service:



public class MyService(ILogger<MyService> logger) : BackgroundService
{
    private readonly ILogger<MyService> _logger = logger;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            _logger.LogInformation("MyService running at: {time}", DateTimeOffset.Now);
            await Task.Delay(1000, stoppingToken);
        }
    }

}

Add this to the main class:


var builder = Host.CreateApplicationBuilder(args);

IConfiguration configuration = new ConfigurationBuilder()
        .SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
        .AddJsonFile("appSettings.json", false)
        .Build();

builder.Services.AddSingleton(configuration);

builder.Services.AddHostedService<MyService>();

builder.Services.AddWindowsService(options =>
{
    options.ServiceName = "MyServiceName";
});

builder.Services.AddLogging((o) =>
{
    o.ClearProviders();
    o.AddNLog();
});


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

Use powershell to install the service:


New-Service -Name "MyService" -BinaryPathName "C:\path\to\MyService.exe" -StartupType Automatic 

Another thing to remember is to set the current working directory, or else, the appsettings.json and other files won't be accessible:

Directory.SetCurrentDirectory(System.AppDomain.CurrentDomain.BaseDirectory);

Alternative way to schedule the periodic task

Use NCronJob package instead


builder.Services.AddTransient<MyWorkerService>();

builder.Services.AddNCronJob(options =>
    options.AddJob<MyWorkerService>(j =>
    {
        //Use - https://crontab.guru/
        j.WithCronExpression("0/30 * * * *");
    }    
));

Then create the service:


public class MyWorkerService: IJob {
  public async Task RunAsync(IJobExecutionContext context, CancellationToken token)
  {
      //await RunSomething(token);
  }
}

Post a Comment

Previous Post Next Post