Windows Service in C#

Microsoft Windows services, formerly known as NT services, enable you to create long-running executable applications that run in their own Windows sessions. These services can be automatically started when the computer boots, can be paused and restarted, and do not show any user interface. These features make services ideal for use on a server or whenever you need long-running functionality that does not interfere with other users who are working on the same computer.

We use the timer event to run the service at regular time interval.If you define the Windows Service to start automatically, you need not worry about starting the timer again; this background process will keep on running until you stop the service and disable it. Since this is a background process, there will not be a user interface to dialog with the user. In case of exceptions, messages would be written to the Windows Event Log. The Timer class belongs to System.Timers namespace. And we are intereseted in Elapsed events and Interval, AutoReset and Enabled properties. The Start() methof of the Timer class kick start the process.

Elapsed - Everything in the timer evolves around the Elapsed event, which is the event that is raised every interval. You create code to be executed and call that code in the Elapsed event. Most likely this is getting set in the OnStart() method of service. Interval - This is used to set the time interval between raising the Elapsed event. AutoReset - Ensures that the timer will be reset after every Elapse event. if this is set to False, Elapse event get executed once. The default value for AutoReset property is true. Enabled - you need to set this to true to start the timer.

Every service is having a static Main() method, where you issue a Run command, which loads the service into the Services Control Manager. Visual Studio will create this code snap automatically.

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace TestService
{
    static class Program
    {
        /// 
        /// The main entry point for the application.
        /// 
        static void Main()
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
			{ 
				new TestService() 
			};
            ServiceBase.Run(ServicesToRun);
        }
    }
}

I am using VS 2008 here. Create a new project and select Windows Service.

This will a a new Service file called. Services.cs. Delete that add that one with the name you needed. This can be done by right click on the project and add a New Item. In my case I added a new service called TestService.

We need to change the Program.cs file to Load the right Service.

Add a System.Timers.Timer object which drive the service execution. The full source code is below.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;
using System.Threading;

namespace TestService
{
    partial class TestService : ServiceBase
    {
        private System.Timers.Timer timer = new System.Timers.Timer();
        double dServicePollInterval;

        public TestService()
        {
            InitializeComponent();
            dServicePollInterval = 10000;
        }

        protected override void OnStart(string[] args)
        {
            // TODO: Add code here to start your service.
            timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
            //providing the time in miliseconds
            timer.Interval = dServicePollInterval;
            timer.AutoReset = true;
            timer.Enabled = true;
            timer.Start();
            //Counter = Counter + 1;
        }

        void timer_Elapsed (object sender, EventArgs e)
        {
            FileStream fs = new FileStream(@"c:\TestWindowsService.txt", FileMode.OpenOrCreate, FileAccess.Write);
            StreamWriter m_streamWriter = new StreamWriter(fs);

                m_streamWriter.BaseStream.Seek(0, SeekOrigin.End);
                m_streamWriter.WriteLine(" GigyService : Service Started " + DateTime.Now.ToLongTimeString());
                m_streamWriter.Flush();
                m_streamWriter.Close();
        }

        protected override void OnStop()
        {
            timer.Stop();
        }
    }
}

And the Program.cs file code is below.

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;

namespace TestService
{
    static class Program
    {
        /// 
        /// The main entry point for the application.
        /// 
        static void Main()
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
			{ 
				new TestService() 
			};
            ServiceBase.Run(ServicesToRun);
        }
    }
}

Main() is the entry point for the service execution. Since ServicesToRun is an array above, if we want we can have more than one service here to get instantiated. The Run() here is a static method which each services in the passed array. OnStart() is the important method in the TestService. This wire up the event for the timer, sets it interval and start the timer. One of the great things about using a Timer with a Windows Service is that its counter runs in a separate thread. So, in your OnStart event only assign your EventHandlers and start your Timer. Perform the actual functionality of your service from the Timer's tick event. This will allow for a quick startup of your service.

Add a ProjectInstaller.cs file as below. During installation this file is used. We can use the installer commandline utility to get this installed. We can add the ProjectInstaller file in two. Right click on the services design page and Select the Add Installer from the popup or from the Services property page click the Add Installer link Which is all the what down


We can use the command line utility to deploy the service.

This will create two Install log files one for the service and for InstallUtility.

Please make sure that the Service account to Local system to avoid the below screen during installation.


Reference Articles