Create a Windows service (a) using .NET Core - the recommended way to use the official

Original: Creating Windows Services In .NET Core - Part 1 - The "Microsoft" Way
Author: Dotnet Core Tutorials
Translator: Lamond Lu
asked: - the use of official recommended way to create a Windows service (a) the use of .NET Core

Create a Windows service to run batch jobs or run background tasks, it is a very common pattern, but due to the proliferation of cloud services (Amazon Lambda, Azure WebJobs and Azure Functions), you probably will not use a Windows service. Personally, I like to use Azure WebJobs, because I can write directly to a console application, without the need to consider how to run it in the cloud, a batch file can be loaded into an automated task and can guarantee 7 * run for 24 hours.

But maybe you're not using cloud services, or if you want to have a bunch of legacy applications as Windows services that run needs to be converted to .NET Core, but can not fully convert them to "serverless" (serverless) applications. So here is the article for you.

In many respects, exactly the same as the .NET Core Windows services and .NET Framework in Windows services. However, at the time of writing services, you may encounter some minor problems. In addition, this paper, we introduce only create a Windows Service "Microsoft" way, in the follow-up, I will continue to introduce how to use third-party libraries TopShelfto simplify the process it.

installation

Because Visual Studio does not provide a template to create a Windows service, so we need to create a Windows service by creating a console program approach.

Once created, we need to install a Nuget package, this package will add some Windows specific API to .NET Core, these API actually provides a complete framework, but many of which are Windows-specific, for example, Windows services. Thus, they are not included in the base .NET Core library, but can be introduced into the .NET Core by way Nuget package.
Here we can enter the following command in the Package Manager Console.

Install-Package Microsoft.Windows.Compatibility

Code

Nuget package introduced above, the most we are interested in ServiceBasethe class. This is the base class for writing a Windows service, which provides a series of events hook, include service start, end, pause, and so on.

Below it, we will create a class in your code, this class is responsible for some of the simple log output to a temporary file. We will use this example to understand the principles involved. Our code is as follows:

class LoggingService : ServiceBase
{
    private const string _logFileLocation = @"C:\temp\servicelog.txt";
 
    private void Log(string logMessage)
    {
        Directory.CreateDirectory(Path.GetDirectoryName(_logFileLocation));
        File.AppendAllText(_logFileLocation, DateTime.UtcNow.ToString() + " : " + logMessage + Environment.NewLine);
    }
 
    protected override void OnStart(string[] args)
    {
        Log("Starting");
        base.OnStart(args);
    }
 
    protected override void OnStop()
    {
        Log("Stopping");
        base.OnStop();
    }
 
    protected override void OnPause()
    {
        Log("Pausing");
        base.OnPause();
    }
}

So here you will notice that our class is inherited ServiceBaseclass, and we rewrote several events method, the output of some of the log. When the service starts, it will trigger the OnStartevent, at the time of termination of service, will trigger OnStopevents. Here we should not be too onerous task placed in the OnStartevent to handle.

If we wanted from the Mainstart the service, the code is very simple.

static void Main(string[] args)
{
    ServiceBase.Run(new LoggingService());
}

That's all the code.

Service Deployment

When publishing service, we can not only rely on Visual Studio to build the services we need, we also need to be specially built for Windows is running. To this end, we need to run the following command at the command prompt project root directory. Note that here we pass a -rflag to tell it to build the platform.

dotnet publish -r win-x64 -c Release

After the command has finished running, we can check the following /bin/release/netcoreappX.X/publishdirectory, we can find all the published code, but most importantly, where we can get a exe executable file. If you do not specify when we run, we will only get a .NET Core of dll assembly, use this assembly, we have no way to create Windows services.

Now we can move this release directory with any other place, but now we temporarily use the current release directory.

Next, we need to use the Administrator role Open a command prompt and enter the following command.

sc create TestService BinPath=C:\full\path\to\publish\dir\WindowsServiceExample.exe

SCCommand is a standard Windows command (nothing to do with .NET Core), which can be used to install Windows service. Here we will test our service is named TestService, more importantly, we passed BinPaththe specified executable exe file parameters.

After running, we should get the following results.

[SC] CreateService SUCCESS

Then we have to do is start the service.

sc start TestService

Now we can look at our log file to see the operation of the service.

If you want to stop and remove the service, we can use the following command.

sc stop TestService
sc delete TestService

Services Debugging

Here, I really believe that the use of "Microsoft" way doomed to failure. Since commissioning services is too cumbersome.

First, we will ServiceBaseoverride methods to protected, which means that we can not access them outside the class, which makes them more difficult to debug. Here I found that the best approach is to provide a public method for each event and these public method calls in a protected method to completion, although this is a bit confusing,

public void OnStartPublic(string[] args)
{
    Log("Starting");
}
 
protected override void OnStart(string[] args)
{
    OnStartPublic(args);
    base.OnStart(args);
}

But at least we can do the following things.

static void Main(string[] args)
{
    var loggingService = new LoggingService();
    if (true)   //Some check to see if we are in debug mode (Either #IF Debug etc or an app setting)
    {
        loggingService.OnStartPublic(new string[0]);
        while(true)
        {
            //Just spin wait here. 
            Thread.Sleep(1000);
        }
        //Call stop here etc. 
    }
    else
    {
        ServiceBase.Run(new LoggingService());
    }
}

Your other option is carried out in debug mode project release, installation services, and then attach the debugger. In fact, this is the way Microsoft recommends that you use, but I think this is simply a mess.

Follow-up

In fact, here we can do some other useful things, like we can run the SC Create command for us by creating a batch file install.bat. But I think we have seen above, debugging problems, has made me no longer want to use this way of. Fortunately, there is a named Topshelflibrary can help alleviate a lot of trouble, in the next part of this series, we will examine how it is.

Guess you like

Origin www.cnblogs.com/lwqlun/p/11621186.html