Creating a Windows Service using .Net Core 2.2

Up until very recently, creating a Windows Service was the domain of the .Net Framework. However, since the release of the Windows Compatibility Pack that has all changed. In this article, we’ll create a .Net Core Windows Service from scratch.

I’m using the preview version of Visual Studio 2019 for this post. As far as I’m aware, there is absolutely no functional difference between this and VS2017; however, the initial New Project screen does look a little different.

Create the Project

There are no “New Windows Service (.Net Core)” options in Visual Studio, so we’re just going to create a console application (everything is a console application in .Net Core):

The .Net Core application can target .Net Core 2.2:

Windows Compatibility

The next step is to install the Windows Compatibility NuGet package:

Install-Package Microsoft.Windows.Compatibility

Write the Service

Let’s start with the main method:

static void Main(string[] args)
    using (var service = new TestSevice())

You’ll need to Ctrl-. ServiceBase. TestService doesn’t exist yet, so let’s create that:

internal class TestSevice : ServiceBase
    public TestSevice()
        ServiceName = "TestService";

    protected override void OnStart(string[] args)
        string filename = CheckFileExists();
        File.AppendAllText(filename, $"{DateTime.Now} started.{Environment.NewLine}");

    protected override void OnStop()
        string filename = CheckFileExists();
        File.AppendAllText(filename, $"{DateTime.Now} stopped.{Environment.NewLine}");

    private static string CheckFileExists()
        string filename = @"c:\tmp\MyService.txt";
        if (!File.Exists(filename))

        return filename;


Not exactly a complicated service, I’ll grant you.


For Framework apps, you could use InstallUtil, but if you try that on a Core app, you get an annoyingly vague error! Instead, you need to find the place where the binary has been compiled; for example:


Now, launch a command prompt as admin, and type the following:

>sc create [service name] binpath=[full path to binary]

For example:

>sc create pcmtestservice binpath=C:\Users\pcmic\source\repos\ConsoleApp3\ConsoleApp3\bin\Debug\netcoreapp2.2\ConsoleApp3.exe

You should get the response:

[SC] CreateService SUCCESS

You can then either start the service from here:

>sc start pcmtestservice

Or locate it in the services utility and start it from there. You should now be able to start and stop the service and see it logging the events as you do so.

If you need to remove the service, use:

>sc delete pcmtestservice


26 thoughts on “Creating a Windows Service using .Net Core 2.2

  1. Renin

    Thank you so much for the information which is very clear. One thing I faced while implementing this is , I couldn’t generate a exe file, instead I am getting the dll. I have gone through several articles , but may I know if you have any suggestions ?

  2. pcmichaels Post author

    I had a similar issue myself. I was initially under the impression that you could simply create a class library and the service controller would manage it: but you need to create it as a console application. If you have done, then check the properties of the console app project to check the output type is set to exe.

    1. Renin

      Thank you for the response. To be honest I tried to put the output type as Windows Application already (Remaining two are console and class library). But still it is generating the dlls 🙁

      1. pcmichaels Post author

        For this particular article, you’ll need console app – which is what it will be set to if you generate a console app from scratch. If you change it to console app and you don’t start getting an exe, make sure you’re looking in the right directory: remember that the binaries will only be in the debug directory above if you’re running in debug mode; otherwise they’ll be in release.

  3. Dan

    Very helpful!
    I came across several articles with instructions on creating a windows service in .net core, some even for 2.2, but none as straightforward and simple as this. I assume that with 2.2 the process has become much simpler, and the other articles just weren’t up-to-date.
    About the dll/exe problem that the other readers have described – I had the same problem.
    After reading this:
    I realized that it’s actually by design, and only by adding a RuntimeIdentifier to the csproj, an exe will generated:


    Actually the app itself is still generated as a dll, but now an additional exe with the same same is generated, which only serves to run the dll.
    From your comment it appears that you get an exe without this fiddling. Can you please explain how?

    1. Dan

      Sorry, I didn’t realize I should have escaped the brackets. The csproj snippet should be:

  4. SteveHarveyUK

    Hi Dan,
    Found this article and am trying it on a project that was previously .NET Framework, with a runtime Application/Service using the ServiceBase and ServiceBase.Run() pattern. I’m seeing something really bizarre.
    Everything builds and both net472 & netcoreapp2.2 work as console apps. The net472 service version also works fine, but the netcoreapp2.2 service just gets a StartService FAILED 1053 message even though I can see logging indicating that it’s working. Obviously, the netcoreapp2.2 service then get shut down.

    It’s very frustrating to be so close… Both frameworks are using the exact same ServerBase implementation. Any ideas what it could be?

      1. SteveHarveyUK

        Looks like I was missing something silly. Apparently the switch I’m using to toggle between console and service mode doesn’t work when running as a netcoreapp2.2 service. Basically, Environment.UserInteractive = True in netcreapp2.2 while it is false in net472.

  5. Dheeraj Kumar


    thanks to your blog i am able to create a window service on .NET Core 2.2 and install it on Windows 10 Machine/laptop.

    I am not able to install it on Windows 2016 Std. 64 bit properly. When i run SC create command then it run successfully and service gets created successfully.

    but when i try to run it gives me (within 1 sec) Error 1053

    can you Please help me here to resolve this issue.

        1. pcmichaels Post author

          IIRC at the time of writing this, they hadn’t quite got the tooling right (hence the use of SC.EXE). You’d probably need a custom step in your deployment tool of choice (wix/install shield/etc).

  6. Yaheya M Quazi

    Thanks for the article this was really helpful. I was able to do the console app with no trouble. Now I want to do the same for .net core App Web App running MVC model. I followed the same steps, created the service, but the service is not starting. Any help would be highle appreciated.

    1. Andy

      For web apps in MVC model, you will need to create a different project type: Asp.Net Core. This post is targeting to create a windows service from .net core 2.2.

  7. Louis De Grazia

    Helpful, thank you.

    To help others you have to make the text file in c tmp first. You will see event viewer error:

    Description: The process was terminated due to an unhandled exception.
    Exception Info: System.IO.DirectoryNotFoundException: Could not find a part of the path ‘c:\tmp\MyService.txt’.
    at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)

    Also, you have to package the app as a self contained exe as others stated above.


  8. FPX

    Ran into a few problems with this. Had the same problem. A couple of common problems that hurt newbies

    1) The = sign is part of the command not the value (ex binpath= “somepath” – | binpath = “” -)

    2) Need quotes around the path “c:/yourpath” – c:/yourpath – WRONG

    3) If you are running the service locally omit the server name. ONLY user the server name if you are publishing service to remote computer

    1. pcmichaels Post author

      Hi – thanks for reading and commenting.

      It’s been a while since I wrote this, so maybe some of the formatting is messed up, but the bin path seems fine. Regarding the quotes – they are only necessary if you have a space in the file name. I’m also not too sure where you’re referring to the server name.

  9. Kenneth Carter

    I have VS 2017 and I have installed 3.1.0
    I have the 2.2.109 installed for the .net core runtime.

    the class ServiceBase can not be resolved. does anyone know what is going on?

  10. Mattitude

    Thank you so much for posting this!
    It seemed like Microsoft pulled support for .NET Core 2.1 Windows services, to encourage upgrading to the new Visual Studio 2019 ($45/month, $800/license for pro).
    This post gave me the proof of concept that this was not the case.
    Here are my steps for converting my .NET Core 2.1 Web API to a Windows service:
    [x] Proof of concept (your post)
    [x] Install the proper nuget packages
    [x] Install-Package Microsoft.Windows.Compatibility -Version 2.1.1
    [x] Publish as .exe
    [x] sc create TestService binpath=”C:\bin\Release\netcoreapp2.1\win-x64\.exe”
    [X] Convert API to Windows Service – locally
    [x] Install the proper nuget packages
    [x] Install-Package Microsoft.AspNetCore.Hosting.WindowsServices -Version 2.1.1
    [x] Install-Package Microsoft.Extensions.Logging.EventLog -Version 2.1.1
    [x] Implement Args:
    [x] No Args, run as custom service
    [x] Publish as .exe
    [x] sc create TestService binpath=”C:\bin\Release\netcoreapp2.1\win-x64\.exe”
    [x] Run/Test Service
    [x] Change logon Rights
    [x] Verify that local debugging still works

    [x] Convert API to Windows Service – In Prod
    [x] Publish as .exe
    [x] sc create TestService binpath=”C:\bin\Release\netcoreapp2.1\win-x64\.exe”
    [x] Run/Test Service
    [x] Change logon Rights

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.