Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Writing Windows Service (C# .NET)

0.00/5 (No votes)
7 Sep 2015 1  
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'.

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.

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.

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.

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:

private System.Timers.Timer timer;

Initialize it inside the constructor:

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.

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

and stop the timer in OnStop function with:

timer.Stop();

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

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:

using System.Configuration.Install;

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

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.

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

Then paste the following methods:

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.

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.

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:

sc delete ServiceName

Good luck.

History

  • 7th September, 2015: Initial version

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here