如何调试 Windows 服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5064327/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to Debug a Windows Service
提问by Simsons
I have create a windows service using the Code ProjectArticle. I am able to install the service and delete the service using -i and -d switch.
我使用代码项目文章创建了一个 Windows 服务。我可以使用 -i 和 -d 开关安装该服务并删除该服务。
I am able to see the service in services.msc but when I start the service it does nothing.Below I will proide the service main code:
我可以在 services.msc 中看到该服务,但是当我启动该服务时它什么也不做。下面我将提供服务主要代码:
void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
DWORD status;
DWORD specificError;
m_ServiceStatus.dwServiceType = SERVICE_WIN32;
m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
m_ServiceStatus.dwWin32ExitCode = 0;
m_ServiceStatus.dwServiceSpecificExitCode = 0;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
m_ServiceStatusHandle = RegisterServiceCtrlHandler("Service1",
ServiceCtrlHandler);
if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
return;
}
m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
m_ServiceStatus.dwCheckPoint = 0;
m_ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus))
{
}
bRunning=true;
while(bRunning)
{
Sleep(150000);
ShellExecute(NULL, "open", "C:\", NULL, NULL, SW_SHOWNORMAL);
}
return;
}
But while I start the service neither it sleeps or starts the explorer. Am I missing anything?
但是当我启动服务时,它既不休眠也不启动资源管理器。我错过了什么吗?
回答by Ian Goldby
Ferruccio's suggestion to attach a debugger to the running service is a good one, as is the suggestion to include an option to run as a console application (though that won't help in your case).
Ferruccio 建议将调试器附加到正在运行的服务是一个很好的建议,建议包括一个作为控制台应用程序运行的选项(尽管这对您的情况没有帮助)。
To debug the startup code, you can call DebugBreak()at the beginning of your startup code. That will launch the debugger and pause execution of your service at that point. Once you are in the debugger, set whatever breakpoints you need and then continue execution.
要调试启动代码,您可以在启动代码的开头调用DebugBreak()。这将启动调试器并在那时暂停您的服务的执行。进入调试器后,设置所需的任何断点,然后继续执行。
回答by Ferruccio
You can always build a service in debug mode and attach a debugger to the running service. The only problem with this technique is that you can't debug the service start-up code. For this reason and for the fact that it can be a pain to be constantly registering/unregistering/starting/stopping a service in order to debug it, I always write services so that they can also be run as command line programs.
您始终可以在调试模式下构建服务并将调试器附加到正在运行的服务。这种技术的唯一问题是您无法调试服务启动代码。出于这个原因,并且由于不断注册/取消注册/启动/停止服务以调试它可能很痛苦,我总是编写服务,以便它们也可以作为命令行程序运行。
Your service can tell that it was started from the command line if StartServiceCtrlDispatcher()
fails and GetLastError()
returns ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
.
如果StartServiceCtrlDispatcher()
失败并GetLastError()
返回,您的服务可以判断它是从命令行启动的ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
。
Of course, when you run a service from the command line it has access to the desktop, which a service normally doesn't and it's running in the context of the currently logged in user, rather than LocalSystem or a specified account so you need to take these differences into account when debugging a service in this manner.
当然,当您从命令行运行服务时,它可以访问桌面,而服务通常不会访问桌面,并且它在当前登录用户的上下文中运行,而不是在 LocalSystem 或指定帐户中运行,因此您需要以这种方式调试服务时,请考虑这些差异。
回答by Praveen Patel
Use below code to debug your service, put this in service startup function, it will give you a popup and hold the execution until you say OK or until 60 seconds, put the breakpoint in the next execution statement and you can proceed with debugging -
使用下面的代码来调试你的服务,把它放在服务启动函数中,它会给你一个弹出窗口并保持执行直到你说 OK 或直到 60 秒,把断点放在下一个执行语句中,你可以继续调试 -
Include this header-
包括这个标题-
#include <Wtsapi32.h>
#pragma comment( lib, "Wtsapi32.lib" )
Code-
代码-
wchar_t title[] = L"mrnservice in startup - 60 seconds to take action";
wchar_t message[] = L"To debug, first attach to the process with Visual "
L"Studio, then click OK. If you don't want to debug, "
L"just click OK without attaching";
DWORD consoleSession = ::WTSGetActiveConsoleSessionId();
DWORD response;
BOOL ret = ::WTSSendMessage( WTS_CURRENT_SERVER_HANDLE,
consoleSession,
title, sizeof(title),
message, sizeof(message),
MB_OK,
60,
&response,
TRUE );
回答by OJ.
Services are headless, so trying to fire up anything GUI related will result in no visible effect. ShellExecute would fire up an application in the visual context of the service, which your desktop will not be able to see.
服务是无头的,所以尝试启动任何与 GUI 相关的东西都不会产生明显的效果。ShellExecute 将在服务的可视上下文中启动应用程序,您的桌面将无法看到该应用程序。
If you want to prove that your service is doing something, write something to file system instead (or trust that it's running given the service manager is rather well equipped to tell you if it's not).
如果您想证明您的服务正在做某事,请改为向文件系统写入一些内容(或者相信它正在运行,因为服务管理器非常有能力告诉您它是否正在运行)。
回答by AudioDroid
I would recommend to write a little Logger-Class, that writes information to a text-file. Then you can e.g. put something like:
我建议编写一个小的 Logger-Class,将信息写入文本文件。然后你可以放一些类似的东西:
if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
Logger.LogError("Service handler is 0.");
return;
}
while(running) {
Logger.LogInfo("I am running.");
//...
}
回答by the_mandrill
I've got some general tips on debugging windows services here, though at first glance I think it's the fact that you're using ShellExecute
which requires desktop interaction. A service typically runs on a LocalService
account so it has no connection to a physical desktop.
我已经有了调试窗口服务的一般提示这里,虽然乍一看我认为这是事实,你正在使用ShellExecute
需要桌面交互。服务通常在一个LocalService
帐户上运行,因此它与物理桌面没有连接。
回答by deepak_
Alternatively, OutputDebugString() can be put in the service app and prints can be seen in DbgView. I have done it to debug my service application. Hope this helps somebody..
或者,可以将 OutputDebugString() 放在服务应用程序中,并在 DbgView 中查看打印件。我这样做是为了调试我的服务应用程序。希望这可以帮助某人..