65.9K
CodeProject 正在变化。 阅读更多。
Home

如何在 Visual Studio 2008 中启动和调试 Windows 服务

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.71/5 (4投票s)

2008年7月18日

LGPL3

2分钟阅读

viewsIcon

55219

downloadIcon

189

本文演示了如何使用 Visual Studio 2008 启动和调试 Windows 服务。

引言

本文演示了如何使用 Visual Studio 2008 启动和调试 Windows 服务。它同样适用于 Visual Studio 2005。

背景

在使用 Visual Studio 开发 Windows 服务时,通常需要使用服务控制管理器启动 Windows 服务,然后将调试器附加到该进程。但这不是必须的。在大多数情况下,您可以自动化此过程,只需按下 F5 即可。

Using the Code

Visual Studio 可以像 Office 一样被自动化。您可以使用此功能通过按下 F5 来启动和调试 Windows 服务。

为了实现这个目标,在您的 Windows 服务项目的解决方案中创建一个新的 Windows Forms 项目,并将其设置为解决方案的启动项目。将项目命名为 ServiceDebug,并将表单命名为 console

在表单的类中添加一些 Imports

Imports System.ServiceProcess
Imports System.Runtime.InteropServices
Imports System.ComponentModel
Imports EnvDTE

这将使代码更易读。

有两个常量。一个包含 Windows 服务的名称,另一个包含 Windows 服务的可执行文件的完整路径

' Replace the value of this constant with the name of the service.
Private mcsServiceName As String = "INSERT_SERVICE_NAME_HERE"
' Replace the value of this constant with the path of the executable.
Private mcsExecutablePath As String = "INSERT_EXECUTABLE_PATH_HERE"

类中有一个私有变量用于 Visual Studio 自动化对象,DTE。它类似于 Office 的 Application 对象;您可以通过此对象访问 Visual Studio 的几乎所有功能

' Visual Studio Object.
Private mDTE As EnvDTE.DTE

所有工作将在表单的 Load 事件中完成

Private Sub Console_Load(ByVal sender As System.Object, _
                         ByVal e As System.EventArgs) Handles MyBase.Load
' Array with all installed windows services.
Dim aoServices() As ServiceController

Dim bFoundService As Boolean
Dim bFoundProcess As Boolean

第一项任务是找到 Windows 服务并启动它。您可以使用 ServiceController 类来完成此操作

' Search the service.
aoServices = ServiceController.GetServices()

' Loop through all services.
For Each oService As ServiceController In aoServices
    ' Service found?
    If (oService.ServiceName = mcsServiceName) Then
        ' Service found. Set flag.
        bFoundService = True

        ' Check state.
        Select Case oService.Status
            ' Running?
            Case ServiceControllerStatus.Running
                ' Stopped?
            Case ServiceControllerStatus.Stopped
                ' Start it.
                oService.Start()
                ' Paused?
            Case ServiceControllerStatus.Paused
                ' Start it.
                oService.Start()
                ' Something else.
            Case Else
                Throw New Exception("Der Windows-Dienst " + mcsServiceName _
                                  + " kann nicht gestartet werden.")
        End Select
    End If
Next oService

' Raise exception if service not found.
If Not bFoundService Then
    Throw New Exception("Der Windows-Dienst " + mcsServiceName _
                      + " ist nicht installiert.")
End If

第二项任务是找到进程并将 Visual Studio 调试器附加到它。您可以使用 DTE 对象的 Debugger 属性来完成此操作

' Get Visual Studio-Object.
mDTE = CType(Marshal.GetActiveObject("VisualStudio.DTE"), EnvDTE.DTE)

' Search the process.
For Each oEnvDTEProcess As EnvDTE.Process In mDTE.Debugger.LocalProcesses
    Try
        ' Process found?
        If (oEnvDTEProcess.Name = mcsExecutablePath) Then
            ' Process found.
            bFoundProcess = True

            ' Attach to the process.
            oEnvDTEProcess.Attach()
        End If
    Catch ex As Win32Exception
        Debug.Print(ex.ToString)
    Catch ex As COMException
        Debug.Print(ex.ToString)
    End Try
Next oEnvDTEProcess

' Raise exception if process not found.
If Not bFoundProcess Then
    Throw New Exception("Der Prozess " + mcsExecutablePath _
                      + " existiert nicht.")
End If

在表单的 Disposed 事件中,您可以输入类似的代码来停止 Windows 服务,当您关闭表单时

Private Sub Console_Disposed(ByVal sender As Object, _
                             ByVal e As System.EventArgs) Handles Me.Disposed
    ' Array with all installed windows services.
    Dim aoServices() As ServiceController

    ' Flag set if the service was found.
    Dim bFoundService As Boolean

    ' Search the service.
    aoServices = ServiceController.GetServices()

    ' Loop through all services.
    For Each oService As ServiceController In aoServices
        ' Service found?
        If (oService.ServiceName = mcsServiceName) Then
            ' Service found. Set flag.
            bFoundService = True

            ' Check state.
            Select Case oService.Status
                ' Running?
                Case ServiceControllerStatus.Running
                    ' Stop it.
                    oService.Stop()
                    ' Stopped?
                Case ServiceControllerStatus.Stopped
                    ' Paused?
                Case ServiceControllerStatus.Paused
                    ' Stop it.
                    oService.Stop()
                    ' Something else.
                Case Else
                    Throw New Exception("Der Windows-Dienst " + mcsServiceName _
                                      + " kann nicht gestoppt werden.")
            End Select
        End If
    Next oService

    ' Raise exception if service not found.
    If Not bFoundService Then
        Throw New Exception("Der Windows-Dienst " + mcsServiceName _
                          + " ist nicht installiert.")
    End If
End Sub

关注点

这个项目在大多数情况下,可以将使用 Visual Studio 启动和调试 Windows 服务的操作简化为按下 F5。有一个重要的限制。当调试 Windows 服务的启动时,您无法使用此技术。原因对我来说尚不清楚。它看起来像是 Windows 服务的构造函数在调试器附加到进程时已经完成了。如果有人有想法,请告诉我。

历史

  • 2008.07.18:第一次尝试。
© . All rights reserved.