Learn How to Create Dual Mode Windows Services

Monday Feb 8th 2010 by Chris Bennett

Learn how to create a dual mode service so you can run your services as either console apps or through Windows Services.


Windows Services provides a great way to run processes continuously in the background; however, debugging them can sometimes be a challenge.  The debugging problem is exaggerated when you have startup issues.  This can be easily solved by creating a dual mode service.  A dual mode service can run as either a Windows Service or as a console application.  To get started we first create a standard Windows Service project in Microsoft Visual Studio as shown below:

Figure 1 - Project Type

After creating the basic Windows Service project it is a good idea to create a single class which is used to startup and shutdown.  Generally, I recommend using the Constructor for startup and the Dispose method for shutdown and cleanup.  This class which I usually call manager is the initial launching point for the application.  All other threads, timers, objects, etc will need to be launched from this class.  This is important since we will be using this class to start the app in both modes.  Listed below is a simple manager class which creates a single thread timer to perform work once per second. 

  class manager : IDisposable 
     private Timer tmrWork; 
     public manager() 
        tmrWork = new Timer(new TimerCallback(tmrHit), null, 1000, 1000); 
     private void tmrHit(object state) 
        Console.WriteLine("Timer Hit!"); 
        //Perform Work Here ... 
     public void Dispose() 
        tmrWork.Change(System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); 

Next we will need to modify the Service1.cs class created in the project to actually use the manager class and start/stop the service.  You will want to create a private member variable of type manager and create the object in the OnStart method and Dispose of it in the OnStop method as shown below.

  private manager mgr = null; 
  protected override void OnStart(string[] args) 
     mgr = new manager(); 
  protected override void OnStop() 

The basic service itself is almost done minus the install class.  As you may know the install class is used to add the service to the Windows Service Manager during the install process.  I've included the one below for reference.

  public partial class Installer1 : Installer 
     private ServiceInstaller serviceInstaller1; 
     private ServiceProcessInstaller processInstaller; 
     public Installer1() 
        processInstaller = new ServiceProcessInstaller(); 
        serviceInstaller1 = new ServiceInstaller(); 
        processInstaller.Account = ServiceAccount.LocalSystem; 
        serviceInstaller1.StartType = ServiceStartMode.Manual; 
        serviceInstaller1.ServiceName = "Dual Mode Service 1"; 
        Installers.Add(serviceInstaller1); Installers.Add(processInstaller); 

At this point you can create a Setup Project and add the project output to the custom actions for install and uninstall and this service is ready to go; however, at this point it is not able to be run as a console app.  In fact if you do it will simply give an error message stating that it cannot be run outside of Service Manager.  To solve this problem we need to make a couple changes. First we need to change the Output Type under Project Properties from Windows Application to Console Application as shown below:

Figure 2 - Output Type

Next, we need to modify the Main method in the program.cs class to correctly start up in console mode.  To support both modes, the Main method will need to accept a command line parameter which will be used to determine which mode to start in.  For this example, the code expects to see zero parameters for service mode and one for console mode.  The snippet below shows how to modify the Main to accomplish this task.

  static void Main(string[] args) 
     if (args.Count() == 0) 
         //Service Mode 
        ServiceBase[] ServicesToRun; 
        ServicesToRun = new ServiceBase[] 
           new Service1() 
        //Console Mode 
        manager mgr = new manager(); 

In the first half of the if statement, the code used to run as a service is unmodified.  The else side creates a new manager class which launches the process, keeps it running by a Console.ReadLine();  and cleans up when the user presses Enter.  To debug in console mode, it is as simple as adding a command line parameter to the Debug\command line arguments option in the project properties.


The method for creating a dual mode service simplifys the process of debugging; however, it will not be able to completely eliminate the need for testing as a Windows Service.  You should also determine if you actually need console mode to be deployed in the final product.  If you do not want console mode to be used outside of development, then you should use conditional compile statements or a command line password.  In addition it is a good idea to adapt common routines such as logging which can provide console output in console mode and another type of loggin service mode.

Click here to download the project example.

About the Author

Chris Bennett with Crowe Horwath LLP in the Indianapolis office. He can be reached at chris .bennett@crowehorwath.com>

Mobile Site | Full Site
Copyright 2017 © QuinStreet Inc. All Rights Reserved