Reader Level:
Articles

Running a Windows Service in Debug Mode

By Akkiraju Ivaturi on September 11, 2012
This article helps in running the Windows Service in debug mode so that we can debug the service to check the flow of code or fixing any of the issues.
  • 1
  • 0
  • 29130

This article helps in running the Windows Service in debug mode so that we can debug the service to check the flow of code or fixing any of the issues. In this article, we are not going to concentrate more on developing a Windows Service rather we concentrate on developing a simple service which opens a Notepad process.

Note: In real-time applications we will not be using a Windows Service to open some application like Notepad but more for creating the code that runs behind the scenes and performs background operations which takes a long duration to complete. For example, we want to check the status of some flag in a table and do an appropriate action and update the flag to something like completed and this should be running 24*7 unless we are in server maintenance.

Open Visual Studio 2010/2008 and create a Windows Service application as below:

Selecting-Windows-Service-Project-Type.jpg

Figure 1: Selecting a Windows Service Project Type

Once the project is created, you will see the following files created for the Windows Service. In this example we are not going to stress out ourselves with creating setup projects or writing too much business logic.

Note: In real-time applications we need to add project installer files and create a setup project to deploy the windows service in the server.

Solution-structure-windows-service.jpg

Figure 2: Solution structure

First things first. The main reason for this article is to identify why we need to do something to make the service that runs an exe. Why cannot a Windows Service be run in your desktop? Why cannot we be debug it directly?

If you are interested in knowing the answers to the preceding questions, do not wait until the end of the article. Just click on the F5 button and see what happens.

alert-in-windows-service.jpg

Figure 3: Alert

You will see the alert by Visual Studio that you cannot start a service from the command line or a debugger. It says that we need to install this service first to run the service. This is good for when we want to deploy it, right? But, what if we want to debug our code to see whether it is running properly or not? Or if we want to debug our code to fix some issue. Of course if we follow Test Driven Development, we should have done unit testing for the code we have developed. But what if we need to check the code in the Windows Service classes? Anyways, the answer is simple: You cannot do that directly.

OK. Now go to the Service1.cs class and check the code. It should be something as in the following:

Service-class-before-customization.jpg

Figure 4: Service class before customization

Here the OnStart() method is what to do to initiate a service and OnStop() takes care of what to do stop the service. If we want to make our service code to be executed for every time interval we may have to add a timer control and add the logic that runs whenever the timer time interval is elapsed.

We cannot use the OnStart and OnStop methods to run the service on your desktop and so we need to write our own methods simulating the OnStart and OnStop methods in the preceding figure.

So here are the steps we need to follow to accomplish the goal of running the Windows Service like an exe file on your desktop and also should be able to debug the code:

1. Declare a static variable of type System.Timers.Timer.

//Declare a timer static variable
private static System.Timers.Timer _aTimer;

2. Add the timer related code in the constructor of the service.

 //Now enable the timer and add an event handler for elapsed
        public Service1()
        {
          _aTimer = 
new System.Timers.Timer(30000);
          _aTimer.Enabled = 
true;
           _aTimer.Elapsed += 
new System.Timers.ElapsedEventHandler(_aTimer_Elapsed);
          InitializeComponent();
        }


3. Write the custom method to start the timer and stop the timer:

//Custom method to Start the timer
 public void Start()
 {
     _aTimer.Start();
 }
 
//Custom method to Stop the timer
 public void
 Stop()
 {
     _aTimer.Stop();
 }


4. Now call the Start() and Stop() methods in the Service class's OnStart and OnStop methods:

 //Call the custom start method
 protected override void OnStart(string[] args)
 {
     
this.Start();
 }
 
//Call the custom stop method
 protected override void OnStop()
 {
     
this.Stop();
 }

5. Handle the Timer Elapsed event.

//Handle the Timer Elapsed event
void _aTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
    
//Create an instance of Process
    Process notePad = new Process();
    
//Set the FileName to "notepad.exe"
    notePad.StartInfo.FileName = "notepad.exe";
    
//Start the process
    notePad.Start();
    
//You may have to write extra code for handling exit code and
    
//other System.Process handling code
}


This completes the changes we have to make in the service class. Now we need to make changes in the Program.cs file.

The main part of achieving the goal is to use preprocessor directives. You can learn more about preprocessor directives from the article posted by Sukesh http://www.c-sharpcorner.com/UploadFile/SukeshMarla/preprocessor-directive-in-C-Sharp/

Do the following changes in the Program.CS file:

  1. Define Preprocessor directive #If DEBUG #else #endif.

  2. Put the actual code already available in the Main method between #else and #endif.

  3. Add your custom logic between #If DEBUG and #else.

Finally our code looks as in the following:

using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading;namespace TestService
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
              #if DEBUG
            //If the mode is in debugging
            //create a new service instance
            Service1 myService = new Service1();
            //call the start method - this will start the Timer.
            myService.Start();
            //Set the Thread to sleep
            Thread.Sleep(60000);
            //Call the Stop method-this will stop the Timer.
            myService.Stop();
#else
            //The following is the default code - You may fine tune
            //the code to create one instance of the service on the top
            //and use the instance variable in both debug and release mode
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
                          { 
                                   new Service1() 
                          };
            ServiceBase.Run(ServicesToRun);
#endif
        }
    }
}


Notice that I have set the Thread.Sleep method to double the time of the timer interval so that it executes only once and then the application is stopped. If you want the code to run in an infinite time period then modify the time from Thread.Sleep(60000) to Thread.Sleep(Timeout.Infinite);

Now let us see how our code runs. Make sure that you set the application running mode as "Debug".

Debug-mode-windows-service.jpg

Figure 5: Debug mode

Press F5. It should open a Notepad file and then it should be done. For convenience I have added variables in custom method and elapsed method to check the timestamps while debugging.

Note: Since I am taking screenshots, the timer may have stopped until I go to the next line and so the timestamps must be approximate.

Start-Method-called-by-the-service.jpg

Figure 6: Start Method called by the service

Timer-Elapsed-code-execution.jpg

Figure 7: Timer Elapsed code execution

Now it has opened a Notepad:

Notepad-instance.jpg

Figure 8: Notepad instance

Stop-method-is-called.jpg

Figure 9: Stop method is called

Finally we forgot to identify one thing. That is we are now not getting the alert when we run. So, it is working like an exe file in debugging mode and works like a service in release mode. This is very convenient and somewhat relaxing in the programmer's life. Is it not?

Try to implement this with proper architecture and at the maximum put the logic in different layer and create unit test projects to test your code and the service should be only calling relevant methods.

In any Enterprise Application projects, we have to develop a Windows Service at least once and hope this helps for the buddy programmers. Hope you enjoyed this article.

Akkiraju Ivaturi

I am a Microsoft Programmer, Architect and blogger. I love resolving complex issues with more than  a decade of  development and software architecture experience. You can follow my blog ilovemicrosoft.blogspot.... Read more

COMMENT USING

Trending up