如何调试 Windows 服务
概要
本文分步介绍了如何使用 WinDbg 调试程序 (windbg.exe) 调试 Windows 服务。 要调试 Windows 服务,可以在服务启动后将 WinDbg 调试程序附加到托管该服务的进程,或者可以配置服务以在启动时附加 WinDbg 调试程序,以便解决与服务启动相关的问题。 本文将介绍这两种方法。
服务启动后将 WinDbg 调试程序附加到服务
此方法与你用于将调试程序附加到进程然后调试进程的方法类似。
使用托管要调试服务的进程的进程 ID
- 若要确定托管要调试服务的进程的进程 ID (PID),请使用以下任一方法。
方法 1: 使用任务管理器
- 右键单击任务栏,然后单击
“任务管理器”。 随即显示“Windows 任务管理器”对话框。 - 单击“Windows 任务管理器”对话框的
“进程”选项卡。 - 在“映像名称”下,单击托管要调试服务的进程的映像名称。 请注意,此进程的进程 ID 是由
相应的 PID 字段值指定的。
- 右键单击任务栏,然后单击
方法 2: 使用任务列表实用工具 (tlist.exe)
- 单击“开始”,然后单击
“运行”。 随即出现“运行”对话框。 - 在“打开”框中,键入
cmd,然后单击“确定”。 - 在命令提示符处,更改目录路径以显示计算机上的 tlist.exe 文件位置。
注意 tlist.exe 文件通常位于以下目录中: C:\Program Files\Debugging Tools for Windows - 在命令提示符处,键入
tlist 以列出计算机上当前运行的所有进程的映像名称以及进程 ID。
注意 请记下托管要调试服务的进程的进程 ID。
- 单击“开始”,然后单击
- 在命令提示符处,更改目录路径以显示计算机上的 windbg.exe 文件位置。
注意 如果命令提示符未打开,请按照方法 1 的步骤 a 和 b 操作。 windbg.exe 文件通常位于以下目录中: C:\Program Files\Debugging Tools for Windows。 - 在命令提示符下,键入 windbg –p
ProcessID /g 以将 WinDbg 调试程序附加到托管要调试服务的进程。
注意 ProcessID 是托管要调试服务进程的进程 ID 的占位符。
使用托管要调试服务的进程的映像名称
只能在托管要运行服务的进程正好存在一个正在运行的实例时使用此方法。 为此,请按照下列步骤操作:
- 单击“开始”,然后单击
“运行”。 随即出现“运行”对话框。 - 在“打开”框中,键入
cmd,然后单击“确定”以打开命令提示符。 - 在命令提示符处,更改目录路径以显示计算机上的 windbg.exe 文件位置。
注意 windbg.exe 文件通常位于以下目录中: C:\Program Files\Debugging Tools for Windows。
- 在命令提示符下,键入 windbg –pn
ImageName /g 以将 WinDbg 调试程序附加到托管要调试服务的进程。注意 ImageName 是托管要调试服务进程的映像名称的占位符。 “-pn”命令行选项指定
ImageName 命令行参数是进程的映像名称。
启动 WinDbg 调试程序并附加到托管要调试服务的进程
- 启动 Windows 资源管理器。
- 找到计算机上的 windbg.exe 文件。
注意 windbg.exe 文件通常位于以下目录中: C:\Program Files\Debugging Tools for Windows
- 同时运行 windbg.exe 文件和 /g 命令行开关以启动 WinDbg 调试程序。 设置断点后,/g 命令行开关允许跟踪的进程继续运行。
- 在“文件”菜单中,单击“附加到进程”以显示“附加到进程”对话框。
- 单击以选择托管要调试服务的进程相应节点,然后单击
“确定”。 - 在出现的对话框中,单击“是”以保存工作区基本信息。 请注意,现在你可以调试服务的反汇编代码。
配置服务以在启动时附加 WinDbg 调试程序
如果要解决与服务启动相关的问题,可以使用此方法调试服务。
配置“映像文件执行”选项。 为此,请使用下列方法之一:
方法 1: 使用全局标志编辑器 (gflags.exe)
- 启动 Windows 资源管理器。
找到计算机上的 gflags.exe 文件。
注意 gflags.exe 文件通常位于以下目录中: C:\Program Files\Debugging Tools for Windows。
运行 gflags.exe 文件以启动全局标志编辑器。
在“映像文件名称”文本框中,键入托管要调试服务的进程的映像名称。 例如,如果要调试由映像名称为 MyService.exe 的进程托管的服务,请键入
MyService.exe。
在“目标”下,单击以选中“映像文件选项”选项。
在“映像调试程序选项”下,单击以选中“调试程序”复选框。
在“调试程序”文本框中,键入要使用的调试程序的完整路径。 例如,如果要使用 WinDbg 调试程序来调试服务,可以键入与以下路径相似的完整路径: C:\Program Files\Debugging Tools for Windows\windbg.exe。单击“应用”,然后单击,“确定”退出全局标志编辑器。
方法 2: 使用注册表编辑器
- 单击“开始”,然后单击
“运行”。 随即出现“运行”对话框。 - 在“打开”框中,键入
regedit,然后单击“确定”以启动注册表编辑器。 - 重要说明
本部分(或称方法或任务)包含有关如何修改注册表的步骤。 但是,注册表修改不当可能会出现严重问题。 因此,请务必严格按照这些步骤操作。
为了获得进一步的保护,请在修改注册表之前对其进行备份。 这样就可以在出现问题时还原注册表。
有关如何备份与还原注册表的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:322756 如何在 Windows 中备份和还原注册表在注册表编辑器中,找到并右键单击下面的注册表子项:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options - 指向“新建”,然后单击
“项”。 在注册表编辑器的左侧窗格中,注意已选中“新项 #1”(新注册表子项的名称)用于编辑。 - 键入 ImageName 以替换“新项 #1”,然后按 ENTER。
注意 ImageName 是托管要调试服务的进程的映像名称的占位符。 例如,如果要调试由映像名称为 MyService.exe 的进程托管的服务,请键入MyService.exe。 - 右键单击在步骤 e 中创建的注册表子项。
- 指向“新建”,然后单击“字符串值”。 在注册表编辑器的右侧窗格中,注意已选中“新值 #1”(新注册表项的名称)用于编辑。
- 将“新值 #1”替换为“调试程序”,然后按 ENTER。
- 右键单击在步骤 h 中创建的“调试程序”注册表项,然后单击“修改”。 将出现“编辑字符串”对话框。
- 在“数值数据”文本框中,键入
DebuggerPath,然后单击“确定”。
注意 DebuggerPath 是要使用的调试程序完整路径的占位符。 例如,如果要使用 WinDbg 调试程序来调试服务,可以键入与以下路径相似的完整路径:C:\Progra~1\Debugg~1\windbg.exe - 为了让桌面上出现调试程序窗口以及与调试程序交互,请使你的服务可进行交互。 如果你的服务无法进行交互,调试程序将启动,但是你无法看见该调试程序且无法发出命令。 若要使你的服务可进行交互,请使用以下方法之一:
方法 1: 使用“服务”控制台
- 单击“开始”,然后指向“程序”。
- 在“程序”菜单上,指向“管理工具”,然后单击“服务”。 随即显示“服务”控制台。
- 在“服务”控制台右侧窗格中,右键单击“ServiceName”,然后单击“属性”。
注意 ServiceName 是要调试的服务名称的占位符。
在“登录”选项卡上,单击以选中“本地系统帐户”下的“允许服务与桌面交互”复选框,然后单击“确定”。
方法 2: 使用注册表编辑器
- 在注册表编辑器中,找到并单击下面的注册表子项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceName
注意将 ServiceName 替换为要调试的服务的名称。 例如,如果要调试名为 MyService 的服务,请找到并单击以下注册表项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyService - 在注册表编辑器右窗格中的“名称”字段下,右键单击“类型”,然后单击“修改”。 随即出现“编辑 DWORD 值”对话框。
- 将“数值数据”文本框中的文本更改为将当前文本的二进制值和二进制值
0x00000100 作为两个操作数的二进制 OR 操作的结果。 二进制值 0x00000100 对应于计算机上 WinNT.h
头文件中定义的 SERVICE_INTERACTIVE_PROCESS 常量。 此常量指定服务本身具备交互性。
- 服务启动时,该服务与服务控制管理器通信,告知该服务必须启动多长时间(服务的超时时间)。
如果服务控制管理器未在超时时间内收到来自服务的“服务已启动”通知,服务控制管理器将终止托管该服务的进程。 此超时时间通常少于 30 秒。
如果未调整此超时时间,服务控制管理器就会在你尝试调试时终止进程和附加的调试程序。 要调整此超时时间,请按照下列步骤操作:- 在注册表编辑器中,找到并右键单击下面的注册表子项:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
- 指向“新建”,然后单击“DWORD 值”。 在注册表编辑器的右侧窗格中,注意
已选中“新值 #1”(新注册表项的名称)用于编辑。 - 键入 ServicesPipeTimeout 以替换“新值 #1”,然后按 ENTER。
- 右键单击在步骤 c 中创建的“ServicesPipeTimeout”注册表项,然后单击“修改”。 随即出现“编辑 DWORD 值”对话框。
- 在“数值数据”文本框中,键入 TimeoutPeriod,然后单击“确定”
注意 TimeoutPeriod 是你要为服务设置的超时时间(以毫秒为单位)值的占位符。 例如,如果要将超时时间设置为 24 小时(86400000 毫秒),请键入 86400000。 - 重启计算机。 必须重启计算机才能使服务控制管理器应用此更改。
- 在注册表编辑器中,找到并右键单击下面的注册表子项:
- 启动 Windows 服务。 为此,请按照下列步骤操作:
- 单击“开始”,然后指向“程序”。
- 在“程序”菜单上,指向“管理工具”,然后单击
“服务”。 随即显示“服务”控制台。 - 在“服务”控制台右侧窗格中,右键单击 ServiceName,然后单击“启动”。注意 ServiceName 是要调试的服务名称的占位符。
疑难解答
在你尝试跨网络调试服务之前,请确保可从运行服务的计算机上访问该服务所用的符号和源文件。 为此,请使用下列方法之一:
- 至少授予所有人对计算机上的文件夹(包含服务使用的符号和源文件)的读取访问权限。
- 将服务使用的这些符号和源文件复制到运行该服务的计算机上。
如何调试 Windows 服务的更多相关文章
- Windows服务二:测试新建的服务、调试Windows服务
一.测试Windows服务 为了使Windows服务程序能够正常运行,我们需要像创建一般应用程序那样为它创建一个程序的入口点.像其他应用程序一样,Windows服务也是在Program.cs的Main ...
- c#创建、安装、卸载、调试windows服务的简单事例
最近工作中用到了windows服务,对其有深刻理解和丰富经验谈不上,本篇文章只是简单陈诉用c#创建.安装.卸载.调试windows服务的步骤. 一.创建windows服务 1.用VS创建windows ...
- C# Asp.net Quartz.NET作业调度之创建、安装、卸载、调试windows服务的简单事例
一.创建windows服务 1.用VS创建windows服务,结果如下: 2.删除默认生成的Service1.cs文件,然后创建自己的服务文件(如:MyService),并修改Program.cs文件 ...
- .net Windows服务程序和安装程序制作图解 及 VS 2010创建、安装、调试 windows服务(windows service)
.net Windows服务程序和安装程序制作 最近项目中用到window服务程序,以前没接触过,比较陌生,花了两天的时间学习了下,写了个简单的服务,但在制作安装程序的时候,参照网上很多资料,却都制作 ...
- VS创建、安装、调试 windows服务(windows service)
1.创建 windows服务 项目 文件 -> 新建项目 -> 已安装的模板 -> Visual C# -> windows ,在右侧窗口选择"windows 服 ...
- C# VS 2010创建、安装、调试 windows服务(windows service)
在一个应用程序中创建多个 windows 服务的方法和 1083 的解决办法 错误解决方案 ------------------------------------------------------ ...
- 使用C#调试Windows服务模板项目
Windows服务是非常强大的应用程序,可用于在backgorund中执行许多不同类型的任务.他们可以在不需要任何用户登录的情况下启动,并且可以使用除登录用户之外的其他用户帐户运行.但是,如果通过遵循 ...
- 调试windows服务最简单的方法之一
先看一下这段启动代码: using System; using System.Collections.Generic; using System.Linq; using System.ServiceP ...
- C#创建、安装、卸载、调试Windows Service(Windows 服务)的简单教程
前言:Microsoft Windows 服务能够创建在它们自己的 Windows 会话中可长时间运行的可执行应用程序.这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面.这 ...
随机推荐
- STM8L052C6T6液晶LCD驱动过程
首先还是必要的说明,鄙人经验有限,如发现问题还请不吝赐教,反馈到邮箱mr.li.ming@qq.com 使用的液晶屏 单片机引脚 液晶的COM1-COM4分别对应单片机LCD_COM0-LCD_COM ...
- sql特殊日期
--a. 本月的第一天 select dateadd(mm, datediff(mm,0,getdate()), 0) as 本月的第一天 --b. 本月的最后一天 select dateadd(ms ...
- go 学习笔记 ----资源自动回收
在释放局部资源时, 可以用defer管理 Go语言版本基于defer的Mutex用法 func safeRead(Mutex *mu) []byte { mu.Lock() defer mu.Unlo ...
- Unity - 简单实现音频管理系统
简单实现Unity音频管理脚本,便于长短音频的播放控制和音量控制等,核心方法为对象池的应用. 项目地址:AudioPlay - SouthBegonia 包含方法: 持有所有 AudioSource ...
- ubuntu安装texlive2019
1.下载texlive2019的iso文件,清华镜像地址:https://mirrors.tuna.tsinghua.edu.cn/CTAN/systems/texlive/Images/texliv ...
- 使用 ProcessMonitor 找到进程所操作的文件的路径
原文:使用 ProcessMonitor 找到进程所操作的文件的路径 很多系统问题都是可以修的,不需要重装系统,但是最近我还是重装了.发现之前正在玩的一款游戏的存档没有了--因为我原有系统的数据并没有 ...
- postgreSQL 备份+还原多张表
-U表示用户 -h表示主机 -p表示端口号 -t表示表名 -f表示备份后的sql文件的名字 -d表示要恢复数据库名 一.打开cmd 进入postgresql安装路径下的bin文件夹,以我的为例: cd ...
- HTTP协议的认识
1.内容回顾 1.HTTP协议消息的格式: 1.请求(request) 请求方法 路径 HTTP/1.1 \r\n k1:v1\r\n ...\r\n \r\n 请求体 <--这里可以有可以没有 ...
- 换个语言学一下 Golang (8)——指针
定义 所谓指针其实你可以把它想像成一个箭头,这个箭头指向(存储)一个变量的地址. 因为这个箭头本身也需要变量来存储,所以也叫做指针变量. Go的指针不支持那些乱七八糟的指针移位.它就表示一个变量的地址 ...
- 【转载】C#中Convert.ToSingle方法将字符串转换为Float类型
在C#编程过程中,可以使用Convert.ToSingle方法将字符串或者其他可转换为数字的对象变量转换为float类型,Convert.ToSingle方法有多个重载方法,最常使用的一个方法将字符串 ...