如何调试 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 会话中可长时间运行的可执行应用程序.这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面.这 ...
随机推荐
- STM32 系统滴答计时器
;//us与系统滴答的被乘数 ;//ms与系统滴答的被乘数 ;//系统运行秒数 /** * @description:系统滴答计时系统初始化 * @param 无 * @retval 无 */ voi ...
- (十)pdf的构成之交叉引用表
交叉引用表(xref) 其中包含对文档中所有对象的引用.交叉引用表的目的是允许随机访问文件中的对象,因此我们不需要读取整个PDF文档来定位特定对象.每个对象由交叉引用表中的一个条目表示.(该表保存 ...
- ELK学习笔记之使用curl命令操作elasticsearch
0x00 _cat系列 _cat系列提供了一系列查询elasticsearch集群状态的接口.你可以通过执行curl -XGET localhost:9200/_cat 1. 获取所有_cat系列的操 ...
- React+SpringBoot项目部署
静态资源访问配置 https://www.jianshu.com/p/b6e0a0df32ec https://segmentfault.com/q/1010000012240531/a-102000 ...
- 关于SQL中SELECT *(星号)的危害论
听闻有许多人是禁止开发人员在SQL中使用SELECT *的,这里翻译一下StackOverflow的一篇提问,个人认为相当客观 [SELECT *]危害主要有以下几点: 给数据消费者传数据的低效.当你 ...
- C# vb .net实现圆角矩形特效滤镜
在.net中,如何简单快捷地实现Photoshop滤镜组中的圆角矩形效果呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第 ...
- 2019 华云数据java面试笔试题 (含面试题解析)
本人3年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.华云数据等公司offer,岗位是Java后端开发,最终选择去了华云数据. 面试了很多家公司,感觉大部分公司考察的点 ...
- mysql的yearweek 和 weekofyear函数
1.MySQL 的 YEARWEEK 是获取年份和周数的一个函数,函数形式为 YEARWEEK(date[,mode]) 例如 2010-3-14 ,礼拜天 SELECT YEARWEEK('2010 ...
- unittest管理接口用例(数据分离-读取excel)
1.简单读取 #coding=utf-8 #调用封装好的excel读取公共方法 from python_API.common.ReadExcel import ReadExcel import req ...
- Python入门篇-数据结构堆排序Heap Sort
Python入门篇-数据结构堆排序Heap Sort 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.堆Heap 堆是一个完全二叉树 每个非叶子结点都要大于或者等于其左右孩子结点 ...