When you create a Windows Service project under Visual Studio, you may have noticed that the following dialog box appears when you try to run the service:

 

In summary, it is simply impossible to run a Windows Service in Visual Studio, you must necessarily go through the NET START command to start the service after having previously installed it with the command INSTALLUTIL. Except that this method prevents us from easily debugging the Windows Service. As a matter of fact, to debug our code, we must install the service, start it, then link the debugger to the relevant service process from Visual Studio. And by the way, let's keep in mind that we will also have to stop, recompile and restart the windows service in order to load up any change we make to the code. In short, it's kinda annoying :D

 

There is a simpler solution though. We can formulate different compilation directives to detect which mode we are running: RELEASE or DEBUG. If we are in:
- DEBUG mode: we will treat our windows service as a simple client application by displaying a dialog box indicating that the service has started
- RELEASE mode: the operation will remain the same as when we tried to run our Windows Service under Visual Studio. In other words, this mode should be used in production, after the debugging session is complete

 

Our use case will be very simple, we will just be running a Windows service and debugging the WCF service that it hosts. Here are the steps you need to follow:

 

1. Tweaking the code of the windows service: we will add two methods, StartWCFService and StopWCFService, which should start and stop listening to WCF incoming requests respectively. The first method will be called in the OnStart method definition, and the second one will come from the OnStop method. Below is the code:

private ServiceHost host;

public MyWindowsService()
{
    InitializeComponent();
}

protected override void OnStart(string[] args)
{
    StartWCFService();
}

protected override void OnStop()
{
    StopWCFService();
}

public void StartWCFService()
{
    host = new ServiceHost(typeof(IWCFService));
    host.Open();
}

public void StopWCFService()
{
    if (host != null && host.State == CommunicationState.Opened)
    host.Close();
}

 

 

2. Tweaking the Program.cs file: it's in the Main method that we would detect our selected compilation mode. If we are in RELEASE mode, then the windows service is running as usual and if we try to run it in Visual Studio within this mode, we will obviously get the so-called dialog box. If, on the other hand, we are in DEBUG mode, then it gets easier, we directly call the StartWCFService method of the instance of our windows service (so the OnStart method will not be called) and then we display a dialog box to notify the user. When they close the dialog box, the StopWCFService method is called to stop the WCF service (therefore, the actual OnStop method of the Windows service will not be called).

Here is the code of the Main method:

static void Main()
{
    MyWindowsService service = new MyWindowsService();
    #if DEBUG
        service.StartWCFService();
        MessageBox.Show("Le service a démarré...");
        service.StopWCFService();
    #else
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[]
        {
            service
        };
        ServiceBase.Run(ServicesToRun);
    #endif
}

 

I hope this post has been helpful ;-)

 

[Translated from a contribution by Holty Sow]