Click here to Skip to main content
15,887,746 members
Articles / Programming Languages / C# 4.0
Tip/Trick

Writing Windows Service (C# .NET)

Rate me:
Please Sign up or sign in to vote.
4.91/5 (33 votes)
7 Sep 2015CPOL4 min read 79.8K   2.4K   77   21
Learn how you can create Windows Services to perform some useful long running operations in the background.

Introduction

When I was given the task to create the Windows service for the first time, I faced all sorts of issues and almost gave up. In this article, I will show you how you can configure your Windows service to start automatically after installation and do some useful task in the background.

Background

While writing the article, I am assuming that you know what the Windows service is and the benefits of using it. This is not the detailed tutorial for explaining each and everything about the Windows services but in the end, you will be able to structure Windows services really quickly. I do that in about 5 minutes now. So let's get started.

Using the Code

I am using Visual Studio 2013 to develop the Windows service. Open Visual Studio, click on File->New->Project and create the Windows Service project.

Creating Windows Service Project

It will present you with the [Design] of automatically created Service1.cs (Rename the file name if you want but for demo purposes, I will continue with the name Service1), right click anywhere on the design and click 'Add Installer'.

Image 2

After you click on Add Installer, it will create the file ProjectInsaller.cs and open it in [Design] mode with the ServiceInstaller and ServiceProcessInstaller. Save the file. Now, right click on ServiceInstaller1 and click properties.

Image 3

Go to the Properties window and edit the properties. Update the Display Name/Description properties to whatever you want to show in the Service.msc listing. Change the StartType to Automatic if you want it to start automatically on Windows startups. Do not change the Parent [ProjectInstaller]. Save the properties.

Image 4

Now, go back to the ProjectInstaller.cs [Design] window, and this time, select serviceProcessInstaller1, go to its properties. You only have to change the Account. I normally write Windows services under Local Services. You can find articles on which account you should choose.

Image 5

Let's write some code now. Open Service1.cs, you will find two methods there, i.e., OnStart and OnStop. As the names suggests, OnStart is called whenever the service starts and OnStop when the service stops. Windows services are written for long running tasks in the background so you would need to keep it alive. In order to do that, we use a Timer which will call itself after x seconds.

Declare the Timer object in your service1.cs:

C#
private System.Timers.Timer timer;

Initialize it inside the constructor:

C#
timer = new Timer(30000D);  //30000 milliseconds = 30 seconds
timer.AutoReset = true;
timer.Elapsed += new ElapsedEventHandler(timer_elasped); //function that will be called after 30 seconds

Now, in your OnStart function, you need to start the timer to keep the service alive.

C#
try
{
     timer.Start();
}
catch (Exception ex)
{
    //log anywhere
}

and stop the timer in OnStop function with:

C#
timer.Stop();

Declare the event handler for your timer. The main operations that your service should perform must go inside this handler.

C#
private void timer_elasped(object sender, ElapsedEventArgs e)
{
    //it will continue to be called after 30 second intervals
    //do some operation that you want to perform through this service here
}

With the basic structure done, we would now move on to configure it to start automatically after installation because you don't wan't the user to restart the machine to start your service. We should always start it immediately depending upon the requirement.

Go to the Program.cs and add the usings statement to reference the required classes:

C#
using System.Configuration.Install;

Inside the main function, add try catch block and paste the following code inside try block:

C#
if (Environment.UserInteractive)
     ManagedInstallerClass.InstallHelper(new string[] { Assembly.GetExecutingAssembly().Location });
else
     ServiceBase.Run(new Service1());

After that is done, you need to tell the service to run automatically once the installation will be done. Open ProjectInstaller.cs code and add the appropriate references.

C#
using System.ComponentModel;
using System.Configuration.Install;
using System.Diagnostics;
using System.ServiceProcess;

Then paste the following methods:

C#
private void serviceInstaller1_AfterInstall(object sender, InstallEventArgs e)
{
      try
      {
          using (ServiceController sc = new ServiceController
		(serviceInstaller1.ServiceName, Environment.MachineName))
          {
              if (sc.Status != ServiceControllerStatus.Running)
                  sc.Start();
          }
      }
      catch (Exception ee)
      {
          EventLog.WriteEntry("Application", ee.ToString(), EventLogEntryType.Error);
      }
 }

 private void serviceInstaller1_Committed(object sender, InstallEventArgs e)
 {
      try
      {
          using (ServiceController sc = new ServiceController(serviceInstaller1.ServiceName))
          {
              SetRecoveryOptions(sc.ServiceName);
          }
      }
      catch (Exception e1)
      {
          EventLog.WriteEntry("Application", e1.ToString(), EventLogEntryType.Error);
          return;
      }
 }

 static void SetRecoveryOptions(string serviceName)
 {
      int exitCode;
      using (var process = new Process())
      {
           var startInfo = process.StartInfo;
           startInfo.FileName = "sc";
           startInfo.WindowStyle = ProcessWindowStyle.Hidden;

           // tell Windows that the service should restart if it fails
           startInfo.Arguments = string.Format
		("failure \"{0}\" reset= 0 actions= restart/60000", serviceName);

           process.Start();
           process.WaitForExit();
           exitCode = process.ExitCode;
      }

       if (exitCode != 0)
           throw new InvalidOperationException();
 }

Last step in the process is, hookup these events with the serviceInstaller. To do that, open the ProjectInstaller.cs [Design]. Go to the Properties, Select Events and paste the event handler names for AfterInstall and Committed events.

Image 6

In the end, just to test whether or not everything went smoothly, copy the bin folder from your default Visual Studio Project Directory (if it's on same drive as your Windows drive) and paste it on some other drive. Right click on your application.exe file and run it as ADMINISTRATOR. To verify whether or not it's installed and running, click Window+R and type services.msc, press enter, it will open up the window listing all the installed services. Now, search for your service name and see if it's installed and running.

Image 7

In the end, if you want to remove the Windows Service from your machine, open command prompt as administrator, go to the path from where you installed it and type in:

C#
sc delete ServiceName

Good luck.

History

  • 7th September, 2015: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Pakistan Pakistan
I am software developer (C# .Net) and a full time freelancer. I've been working in C# .Net, Vb.Net, WPF/WinForms, WCF, ASP.NET MVC, WebApi, oAuth2.0, jQuery Plugins, KnockoutJs, have experience developing applications with Node. I've a great amount of exposure working with MVVM and entity framework. In short, I'm the technology Ninja and love everything new that comes to the technology world.

Comments and Discussions

 
QuestionSmall correction Pin
Nelek11-Jul-19 0:55
protectorNelek11-Jul-19 0:55 
QuestionThanks Pin
Member 1290914510-Apr-19 20:47
Member 1290914510-Apr-19 20:47 
QuestionThanks and a small correction Pin
Alfredo Colon (Al)6-Dec-16 6:15
Alfredo Colon (Al)6-Dec-16 6:15 
AnswerRe: Thanks and a small correction Pin
Mirza Ali Baig8-Dec-16 14:08
Mirza Ali Baig8-Dec-16 14:08 
QuestionGood Article, save a lot of time Pin
Sohaib Javed4-Dec-15 13:19
Sohaib Javed4-Dec-15 13:19 
QuestionHelped like a hot cake. Pin
hammad-ur-rehman16-Sep-15 2:33
hammad-ur-rehman16-Sep-15 2:33 
AnswerRe: Helped like a hot cake. Pin
Mirza Ali Baig19-Sep-15 7:41
Mirza Ali Baig19-Sep-15 7:41 
GeneralNice work Pin
Member 1055185115-Sep-15 17:20
Member 1055185115-Sep-15 17:20 
GeneralRe: Nice work Pin
Mirza Ali Baig19-Sep-15 7:41
Mirza Ali Baig19-Sep-15 7:41 
QuestionMy vote of 5 Pin
Muhammad Idrees GS14-Sep-15 3:41
Muhammad Idrees GS14-Sep-15 3:41 
AnswerRe: My vote of 5 Pin
Mirza Ali Baig19-Sep-15 7:43
Mirza Ali Baig19-Sep-15 7:43 
SuggestionVisual Studio Express 2013 limitation Pin
ahagel8-Sep-15 16:58
professionalahagel8-Sep-15 16:58 
GeneralRe: Visual Studio Express 2013 limitation Pin
Mirza Ali Baig19-Sep-15 7:44
Mirza Ali Baig19-Sep-15 7:44 
GeneralMy vote of 5 Pin
PVX0078-Sep-15 5:57
PVX0078-Sep-15 5:57 
GeneralRe: My vote of 5 Pin
Mirza Ali Baig8-Sep-15 10:23
Mirza Ali Baig8-Sep-15 10:23 
SuggestionTopShelf Pin
BManfred8-Sep-15 4:16
BManfred8-Sep-15 4:16 
GeneralRe: TopShelf Pin
Mirza Ali Baig8-Sep-15 10:25
Mirza Ali Baig8-Sep-15 10:25 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun7-Sep-15 21:12
Humayun Kabir Mamun7-Sep-15 21:12 
GeneralRe: My vote of 5 Pin
Mirza Ali Baig8-Sep-15 10:25
Mirza Ali Baig8-Sep-15 10:25 
GeneralMy vote of 5 Pin
Rizwan Mahfooz7-Sep-15 8:30
professionalRizwan Mahfooz7-Sep-15 8:30 
Simple and Informative

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.