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

如何调试 Windows 服务而不至于失败

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.86/5 (20投票s)

2007年8月7日

CPOL

4分钟阅读

viewsIcon

136439

downloadIcon

839

一种调试 Windows 服务任何部分的方法。

引言

Windows 服务是我们使用的 Windows 操作系统提供的强大编程工具,它可以在无需用户登录系统的情况下运行程序。

由于 Windows 服务的特性,Visual Studio 无法直接启动服务并对其进行调试。同时,您也无法附加调试器来调试服务的构造函数或 Start 事件。这是因为您无法附加一个尚不存在的进程!

存在多种解决方案:其中一种由 Lee Humphries 在一篇精彩的文章中进行了阐述。但是,如何将调试器附加到我们想要开始调试的程序点呢?嗯,在 .NET 2.0 中是可以做到的,您只需要使用 System.Diagnostic 命名空间中的 Debugger 类。

背景

System.Diagnostic 中的 Debugger 类有一个对我们而言非常重要的方法:Debugger.Launch()

Debugger.Launch() 执行时,它会检查当前进程是否已附加到任何调试器;如果没有,它将打开调试器附加窗口,并提示我们选择要与程序一起使用的合适调试器。然后,您只需要将 Launch() 的调用定位到您希望开始控制服务的代码位置即可。

请参阅下面的代码,这是一个在 Windows 服务 OnStart 事件中初始化调试器的示例

protected override void OnStart(string[] args)
{
    iTest = 1; 
#if (DEBUG) 
    Debugger.Launch(); //<-- Simple form to debug a web services 
#endif 
    timer1.Enabled = true; 
}

当框架执行 Debugger.Launch 方法并提示您选择调试器时,请选择显示服务代码的 VS 实例,然后继续在调试器的控制下运行服务。

您需要将该指令用 #if #endif 子句括起来,因为 Debugger.Launch() 方法也会在 Release 模式下执行(这本不应该发生,但 .NET 2.0 在 Debugger.Launch() 方法中存在一个 bug)。

使用代码

  1. 下载并编译文章中附带的带有 DEBUG 选项的代码。
  2. 代码是一个简单的 Windows 服务,它使用一个计时器每 5 秒递增一个整数值。该服务将整数变量的值写入输出窗口。请查看代码中的 Launch() 方法。

  3. 安装 Windows 服务。我建议自动化此任务。我个人在工具 -> 外部工具菜单中创建了两个输入:一个用于安装,另一个用于卸载服务。请参见下图
  4. Screenshot - HowtoDebugaWindowsService.png

    如果您有其他系统来安装/卸载服务,请跳过以下说明

    要为示例 Windows 服务创建安装条目,请单击工具 -> 外部工具 -> 添加,然后输入

    • Title: InstallService
    • Command: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe (使用您的 Windows 安装目录)
    • Argument: WServiceDebug.exe
    • Initial Directory: $(ProjectDir)/bin/debug

    要为示例 Windows 服务创建卸载条目,请单击工具 -> 外部工具 -> 添加,然后输入

    • Title: UnInstallService
    • Command: C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe (使用您的 Windows 安装目录)
    • Argument: /u WServiceDebug.exe
    • Initial Directory: $(ProjectDir)/bin/debug
  5. 在 Visual Studio 中,请确保 Web 服务代码页已打开。
  6. 启动服务。打开服务小程序:控制面板 -> 管理工具 -> 服务。您将看到名为 WServiceDebug 的服务尚未启动。右键单击并选择启动。您将看到打开了选择调试器的对话框。选择已打开 Windows 服务项目的 Visual Studio 实例。转到 Visual Studio,您将看到程序已停止,准备进行调试。按 F5,您将在输出窗口中看到计时器每 5 秒写入整数值。不要启动新的调试器;请使用已编译该服务的 Visual Studio 实例。
  7. 在 Stop 过程中设置一个断点并停止服务。您将看到程序在断点处停止,按 F5 结束调试会话。
  8. 卸载 Windows 服务(使用第 3 点中创建的快捷方式)。然后,在 Release 模式下重新编译应用程序。然后,重新安装 Windows 服务并启动它(您必须修改快捷方式以安装/卸载到初始目录:$(ProjectDir)/bin/release。您将看到调用调试器将不会成功,服务将正常启动。
  9. 在 Debug 模式下重新编译程序,并尝试在服务代码中的 Launch() 方法的各种情况下进行实验。

关注点

使用 System.Debugger.Launch() 方法是解决调试 Windows 服务问题的简单解决方案。我猜想你们中的许多人都在使用这种技术,但我没有找到太多关于这方面的信息(我也没做太多研究)。

历史

  • 2007 年 8 月 7 日 - 初始版本。
© . All rights reserved.