Running a Windows Service as a Console Application

18 May 2012

Edit: Nowadays I would recommend TopShelf. It provides a simple framework for a Windows Service that's easy to debug, install, uninstall, etc.


If you have ever built a Windows Service then trying to debug it can be a problem, having to attach the debugger to a running process is not ideal and I like having the ability to just click "play".

Therefore, with a few changes to a Windows Service, it can be set to run as a console application within Visual Studio for debugging but is actually a Windows Service.

For this to work I am assuming a single service within the same process, if multiple services exist then a different solution will be needed

The Steps

  • Change the Application type in the Project properties to a "Console Application" and the Startup object to "Sub Main".

    Console Application Setting
  • Search the project for "Sub Main" - it is within the main Service1.Designer.vb file.
  • The automatic created code should look like this
    ' The main entry point for the process
         _
         _
        Shared Sub Main()
            Dim ServicesToRun() As System.ServiceProcess.ServiceBase
    
            ' More than one NT Service may run within the same process. To add
            ' another service to this process, change the following line to
            ' create a second service object. For example,
            '
            '   ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1, New MySecondUserService}
            '
            ServicesToRun = New System.ServiceProcess.ServiceBase() {New Service1}
    
            System.ServiceProcess.ServiceBase.Run(ServicesToRun)
        End Sub
    
  • Now this needs editing to create the single service object, then start it. For example:
    ' The main entry point for the process
         _
         _
        Shared Sub Main()
    
            Dim serviceToRun As Service1 = New Service1
    
            If Environment.UserInteractive Then
    
                serviceToRun.OnStart(Nothing)
                Console.WriteLine("Press any key to stop the service")
                Console.Read()
                serviceToRun.OnStop()
    
            Else
    
                ServiceBase.Run(serviceToRun)
    
            End If
    
        End Sub
    

In the modified code I am doing a few key things:

  • Creating the single service:
    Dim serviceToRun As Service1 = New Service1
    in place of the line below that creates an array with one instance:
    ServicesToRun = New System.ServiceProcess.ServiceBase() {New Service1}
  • Added an if statement based on "Environment.UserInteractive" that will be true for when running in Visual Studio.
    If Environment.UserInteractive Then
  • If it's within Visual Studio then the code just starts the service by calling the start sub and then waiting until a Console input.
    serviceToRun.OnStart(Nothing)
                Console.WriteLine("Press any key to stop the service")
                Console.Read()
                serviceToRun.OnStop()
    
  • If not within Visual Studio then it runs the original code to run the service:
    ServiceBase.Run(serviceToRun)
    
Posted by makit
Last revised 22 Jan 2017 11:26 AM

makit / Martyn Kilbryde

Professional software developer, ponderer and eccentric.

flickr

Github

LinkedIn

Stack Overflow

Twitter