Create Window Service In .NET Core

Introduction

This article will teach us how to create a window service with .NET Core using Quartz Cron expression. And host an application as a Windows service on the server machine. Here is another article, How To Create Window Service In .Net Core to create a Windows Service without Quartz Cron expression. 

Step 1

To begin, make a project with the.NET core console application template.

Step 2

Install Required packages for Host Builder using Nuget Package Manager.

Host Builder Introduction

Host Builder is the new “generic” Hostthath that lets developers quickly set up cross-cutting concerns such as logging, configuration, and dependency injection for non-web-focused applications. The team realized that having the host tied to the fears of HTTP was perhaps not an ideal solution since many of these are standard requirements in other application types.

This could be used in a console application that needs to run background processing tasks, perhaps handling messages on a queue example. These types of services are now pretty common in a cloud-native, container-based architecture.

Step 3

Install the required package forQuartzz using Nuget Package Manager.

Also, install quartz using the Package Manager Console as below:

NuGet\Install-Package Quartz -Version 3.4.0

Step 4

Once the package installation is completed, we can write code for the scheduler, which will run after a specific time. Please find below a sample code to write in the program.cs file to write a log at a particular amount of time.

class Program {
    static async Task Main(string[] args) {
        IHost Host = CreateHostBuilder(args).Build();
        await Host.RunAsync();
    }
    public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureServices(services => {
        ConfigureQuartzService(services);
        services.AddScoped < ITaskLogTime, TaskLogTime > ();
    });
    private static void ConfigureQuartzService(IServiceCollection services) {
        // Add the required Quartz.NET services
        services.AddQuartz(q => {
            // Use a Scoped container to create jobs.
            q.UseMicrosoftDependencyInjectionJobFactory();
            // Create a "key" for the job
            var jobKey = new JobKey("Task1");
            // Register the job with the DI container
            q.AddJob < Task1 > (opts => opts.WithIdentity(jobKey));
            // Create a trigger for the job
            q.AddTrigger(opts => opts.ForJob(jobKey) // link to the Task1
                .WithIdentity("Task1-trigger") // give the trigger a unique name
                .WithCronSchedule("0/5 * * * * ?")); // run every 5 seconds
        });
        // Add the Quartz.NET hosted service
        services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
    }
}

Cron Trigger Introduction

As we utilize quartz, we can use a cron trigger. Cron is nothing but a UNIX tool that has been around for a long time, so its scheduling capabilities are robust and proven. The CronTrigger class is based on the scheduling capabilities of cron.

As for POC, I added a cron trigger for 5 seconds with the below expression

"0/5 * * * * ?"

Create a trigger and add it to toQuartzz like the below code,

private static void ConfigureQuartzService(IServiceCollection services) {
    // Add the required Quartz.NET services
    services.AddQuartz(q => {
        // Use a Scoped container to create jobs.
        q.UseMicrosoftDependencyInjectionJobFactory();
        // Create a "key" for the job
        var jobKey = new JobKey("Task1");
        // Register the job with the DI container
        q.AddJob < Task1 > (opts => opts.WithIdentity(jobKey));
        // Create a trigger for the job
        q.AddTrigger(opts => opts.ForJob(jobKey) // link to the Task1
            .WithIdentity("Task1-trigger") // give the trigger a unique name
            .WithCronSchedule("0/5 * * * * ?")); // run every 5 seconds
    });
    // Add the Quartz.NET hosted service
    services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
}

Step 5

Build and Run the application using an exe file. I am attaching the complete source code,e, which will write the log to log.txt file for a current time after every 5 sec as per our cron expression.

Start exe

Check the Log folder for the result

Step 6

We run our application manually using an exe file. Now, sit back and think on the server. Do we run our application like this? Is it a good practic? Not a good idea. So below is the solution.

Host dotnet core console application as a window service

Please follow the below steps to host a console application as a Windows service.

Required Code changes

To support the window service console application, we need to allow UseWindowsService in

CreateHostBuilder met method.

To use window service, you need to install the NuGet package

‘Microsoft.AspNetCore.Hosting.WindowsServices’

To install it by command, use “Install-Package Microsoft.AspNetCore.Hosting.WindowsServices - Version”

NoteYou needed to install the package as per your .NET core version compatibility.

Change in Program.cs file.

public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).UseWindowsService().ConfigureServices(services => {
    ConfigureQuartzService(services);
    services.AddScoped < ITaskLogTime, TaskLogTime > ();
});

Once code changes are done,e Publish the application in Release mode.

After publishing the application, open Command Prompt in administrator mode.

Command To Create Service > SC CREATE "ServiceName" binpath="D:\Published \application\path\application.exe"

Command To Remove Service > SC DELETE ServiceName

Once the service is created. Open press win + R > Type services.msc > Enter.

Service should be visible here by the name you have entered during creation.

Start and stop service from here and change the configuration as per requirement. (I.e., login by another user, automatic or manual)

Advantage

  • The server admin is not required to manually run an exe file on the server.
  • The server admin can set different credentials as per requirement.
  • It can be set as an automatic or manual start. So whenever the server is down and restarted, there is no need to check;k it will automatically start service as per configuration.


Similar Articles