如何调试 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 会话中可长时间运行的可执行应用程序.这些服务可以在计算机启动时自动启动,可以暂停和重新启动而且不显示任何用户界面.这 ...
随机推荐
- 解决docker容器中Centos7系统的中文乱码
解决docker容器中Centos7系统的中文乱码问题有如下两种方案: 第一种只能临时解决中文乱码: 在命令行中执行如下命令: # localedef -i zh_CN -f UTF-8 zh_CN. ...
- php mysqli 预处理操作数据库
用到的SQL表 CREATE TABLE `student_01` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(255) CHARAC ...
- ubuntu Django + Uwsgi + Nginx 的生产环境部署
一.概述 使用runserver可以使我们的django项目很便捷的在本地运行起来,但这只能在局域网内访问,如果在生产环境部署django,就要多考虑一些问题了.比如静态文件处理,安全,效率等等,本篇 ...
- MOOC python笔记(一):python语言概述
python语言简介 特点:简单.易学.使用者多. 荷兰人Guido 1989年发明. 面向对象的解释型计算机程序设计语言. 设计哲学是"优雅"."明确".&q ...
- .NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖
原文:.NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖 我们有多种工具可以将程序集合并成为一个.打包成一个程序集可以避免分发程序的时候带上一堆依赖而出问题. ILMerge 可以用来 ...
- C语言 - 可变参数再stm32中的应用
参考 C 可变参数 | 菜鸟教程 void func(const char* str,...) { ... } func的最后一个参数写成 ... ,表示可变参数, C语言的printf就是类似这种声 ...
- 用HTML、CSS、JS制作圆形进度条(无动画效果)
逻辑 1.首先有一个圆:蓝色的纯净的圆,效果: 2.再来两个半圆,左边一个,右边一个将此蓝色的圆盖住,效果: 此时将右半圆旋转60°,就会漏出底圆,效果: 然后我们再用一个比底圆小的圆去覆盖这个大 ...
- virsh 添加虚拟交换机
virsh 添加虚拟交换机 来源 https://blog.csdn.net/a1987463004/article/details/90905981 vim /etc/libvirt/qemu/ne ...
- Spring Security 解析(一) —— 授权过程
Spring Security 解析(一) -- 授权过程 在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因此决定先把Spring Security .S ...
- k8s维护常用命令
k8s维护 1. 不可调度 kubectl cordon k8s-node-1 kubectl uncordon k8s-node-1 #取消 2.驱逐已经运行的业务容器 kubectl drain ...