Site icon Ryadel

Create a Windows Service in C# using Visual Studio

ASP.NET: Creare un sito web MVC5 con Database MySQL, Entity Framework 6 Code-First e Visual Studio 2013

In this post I'll briefly explain how to create and configure a custom Windows Service in C# using Visual Studio 2019. Before we start, it could be wise to quickly summarize what a Windows Service actually is and how it differs from a standard console program or desktop application.

NOTE: the most recent version of the source code explained in this post is now fully available on GitHub: if you like it, be sure to give it a star!

Introduction

In Windows-based operating systems, the term Windows Service refers to a computer program without a user-interface that completely operates in the background. If you know Unix-based environments, you could think of it as a Windows version of a typical Unix daemon. A Windows service must conform to the interface rules and protocols of the Service Control Manager, the kernel component responsible for managing Windows services.

Once installed, the Windows Service can be configured using the Service Control Manager (services.exe) to start when the operating system is started and run in the background as long as Windows is running; alternatively, they can be started manually or by an event. It's also possible to manually pause, stop and restart the service. 

Each service can also be configured to run within a context of a specific user or system account: for example, most Windows services that come shipped with the OS are pre-configured to run within the context of three system accounts: System, Network Service and Local Service. Such behaviours allow them to operate even when the machine is unmanaged and/or a standard user is not logged on.

To get a glimpse of all services running on a Windows machine you can either:

  • Open Control Panel, then navigate to the Administrative Tools and click on the Services icon.
  • Press Window + R to open the Run window, then type services.msc and press ENTER.
For a list of most - if not all - Windows Services available on Windows 10, take a look at our Windows Services complete list with ShortName and DisplayName post!

Create the Windows Service Project

Open Visual Studio 2019 and select Create a new project from the initial dashboard. Type Windows Service into the filter textbox near the top to quickly find out the project template we're looking for: select the Windows Service (.NET Framework) project template and click Next.

Create a Windows Service in C# using Visual Studio

Give the project a name and create it. After a few seconds, you should be prompted with your newly-created project and a blank page showing the Service1.cs file in Design Mode.

Create an Installer

The next thing we have to do is to create an Installer, which is the component that will register our Service with the Service Control Manager.

To do that, right-click on the blank area in the Design View of the Service1.cs file and select Add Installer from the contextual menu, as shown in the screenshot below:

Once you do that, a new ProjectInstaller.cs file will be added to the project. Save everything (CTRL + SHIFT + S), then open the ProjectInstaller.Designer.cs file and take a look at the InitializeComponent() method, which defines some important settings of our service: its name and display name, the account context used to run it, and so on.

Configure the Installer

Locate the lines defining the Username and Password (both set to null by default) and add the following line right above them to make our service use the LocalSystem account context:

Right after that, locate the line of code defining the ServiceName and change it accordingly:

You can also specify a Display Name and a Description by adding the relevant source code lines, in the following way:

Here's how your InitializeComponent() method should look like after the changes:

That's it for the installer: now let's switch to the Windows Service code itself.

Create a sample recurring task

Open the Service1.cs file and switch to Code View. As we can see, there are three main methods here:

  • the Service1() method, aka the constructor, which internally calls the InitializeComponents() method that we modified in the previous paragraph.
  • The OnStart() method, which is called once when the service is started.
  • The OnStop() method, which will be called once when the service is stopped.

For our sample boilerplate we'll just add a basic timelapse logging feature to the default code:

As we can see, we added the following stuff:

  • The Timer private variable, which host a standard timer (from System.Timers namespace).
  • The Interval private variable, which globally defines the timer interval in milliseconds.
  • The OnElapsedTime() private method, which will be called upon each timer interval cycle.
  • The WriteLog() private method, which logs a custom log message to a daily log file persisted on disk: such file will be created within the folder that hosts the service executable.
  • A minimal implementation in the existing OnStart() and OnStop() methods to put everything together.

While we were there, we also changed the service's default name from Service1 to WindowsService.NET by adding the following line in the constructor, rightbelow the InitializeComponent() call:

Alternatively, the ServiceName property can also be changed from within the Service1.Designer.cs file's InitializeComponent() method.

IMPORTANT: be sure to use the same ServiceName specified in the Service1.Designer.cs class!

That's basically it: our service is ready to be installed and tested!

Installing the Service

To install our service, build the project in Release mode: once done, copy the WindowsService.NET.exe file from /bin/Release/ to a more "handy" folder - such as C:\Temp\WindowsInstaller\.

Right after that, open a Command Prompt with administrative rights and type the following:

You should receive a quick confirmation message saying that everything went good.

Alternative install using SC CREATE

If you don't want to use installutil.exe, you can also install your service using the sc create command with the following syntax:

However, if you do that, you'll have to manually specify the service name: also, the service Description won't be shown in the service list UI window (see below).

Testing the Service

Use Control Panel > Administrative Tools > Services to open the service list and scroll down until you'll find our new service:

That's our boy! From here we can either manually start it or set it to automatic, so that it will be started whenever the system starts. However, I strongly suggest to not do that for now, since it would permanently drain your system resources if you forget to disable it - it's just a sample service after all! Let's just start it and take a look at the log file, which should be found in the executable folder:

If everything went good, the log should be similar to this screenshot:

Removing the Service

To remove our service, open a Command Prompt with administrative rights and type the following command:

Troubleshooting

It's worth noting that, whenever the service encounters an unhandled exceptions while operating, it will crash without writing anything to the Windows event log. For that very reason, I strongly suggest to wrap your main execution methods within a try/catch block and log any possible exceptions on disk - or somewhere else - so you can better understand what's going on. Such task can be very easy using the WriteLog() function within our sample code: don't forget to do that!

Conclusion

That's it: I hope that this guide will help other ASP.NET C# developers to create awesome Windows Services to fullfill their needs! If you like my project, feel free to give me a virtual hug by starring the GitHub project and/or putting a like on our Facebook/Twitter pages!

Exit mobile version