Introduction
This article demonstrates how to start and debug a Windows service with Visual Studio 2008. It will also work with Visual Studio 2005.
Background
When developing a Windows service with Visual Studio, you usually have to start the Windows service with the Service Control Manager, and then you have to attach the debugger to the process. But this is not necessary. You can automate this process in most cases so you only have to press F5.
Using the Code
Visual Studio can be automated just like Office. You can use this feature to start and debug a Windows service by pressing F5.
To achieve this goal, create a new Windows Forms project in the solution of your Windows Service project and make it the startup project of your solution. Name the project ServiceDebug and name the form console
.
Make some Imports
to the class of the form:
Imports System.ServiceProcess
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports EnvDTE
This will make the code more readable.
There are two constants. One contains the name of the Windows service, the other contains the full path to the executable of the Windows service:
Private mcsServiceName As String = "INSERT_SERVICE_NAME_HERE"
Private mcsExecutablePath As String = "INSERT_EXECUTABLE_PATH_HERE"
There is one private variable in the class for the Visual Studio automation object, DTE
. It is comparable to Office's Application
object; you can access almost every functionality of Visual Studio through this object:
Private mDTE As EnvDTE.DTE
All the work will be done in the Load
event of the form:
Private Sub Console_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Dim aoServices() As ServiceController
Dim bFoundService As Boolean
Dim bFoundProcess As Boolean
The first task is to find the Windows service and to start it. You can use the ServiceController
class to do this:
aoServices = ServiceController.GetServices()
For Each oService As ServiceController In aoServices
If (oService.ServiceName = mcsServiceName) Then
bFoundService = True
Select Case oService.Status
Case ServiceControllerStatus.Running
Case ServiceControllerStatus.Stopped
oService.Start()
Case ServiceControllerStatus.Paused
oService.Start()
Case Else
Throw New Exception("Der Windows-Dienst " + mcsServiceName _
+ " kann nicht gestartet werden.")
End Select
End If
Next oService
If Not bFoundService Then
Throw New Exception("Der Windows-Dienst " + mcsServiceName _
+ " ist nicht installiert.")
End If
The second task is to find the process and to attach the Visual Studio debugger to it. You can use the Debugger
property of the DTE
object to do this:
mDTE = CType(Marshal.GetActiveObject("VisualStudio.DTE"), EnvDTE.DTE)
For Each oEnvDTEProcess As EnvDTE.Process In mDTE.Debugger.LocalProcesses
Try
If (oEnvDTEProcess.Name = mcsExecutablePath) Then
bFoundProcess = True
oEnvDTEProcess.Attach()
End If
Catch ex As Win32Exception
Debug.Print(ex.ToString)
Catch ex As COMException
Debug.Print(ex.ToString)
End Try
Next oEnvDTEProcess
If Not bFoundProcess Then
Throw New Exception("Der Prozess " + mcsExecutablePath _
+ " existiert nicht.")
End If
In the Disposed
event of the form, you can enter similar code to stop the Windows service when you close the form:
Private Sub Console_Disposed(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles Me.Disposed
Dim aoServices() As ServiceController
Dim bFoundService As Boolean
aoServices = ServiceController.GetServices()
For Each oService As ServiceController In aoServices
If (oService.ServiceName = mcsServiceName) Then
bFoundService = True
Select Case oService.Status
Case ServiceControllerStatus.Running
oService.Stop()
Case ServiceControllerStatus.Stopped
Case ServiceControllerStatus.Paused
oService.Stop()
Case Else
Throw New Exception("Der Windows-Dienst " + mcsServiceName _
+ " kann nicht gestoppt werden.")
End Select
End If
Next oService
If Not bFoundService Then
Throw New Exception("Der Windows-Dienst " + mcsServiceName _
+ " ist nicht installiert.")
End If
End Sub
Points of Interest
This project will, in most cases, reduce the effort to start and debug a Windows service with Visual Studio to pressing F5. There is one important limitation. When debugging the startup of a Windows service, you cannot use this technique. The reason for this is not clear to me. It just looks like the constructor of the Windows service has already finished when the debugger attaches to the process. If someone has an idea, please let me know.
History