如何用c而不是c调试windows服务启动代码#
每个人 我想知道如何用C调试windows服务启动代码。在C中有几个类似的问题,但它们不是我需要的。 到目前为止,我只能附加到进程进行调试。现在我想调试main()函数,怎么办?越详细越好 非常感谢 我的代码如下 主要功能:如何用c而不是c调试windows服务启动代码#,c,windows,debugging,windows-services,startup,C,Windows,Debugging,Windows Services,Startup,每个人 我想知道如何用C调试windows服务启动代码。在C中有几个类似的问题,但它们不是我需要的。 到目前为止,我只能附加到进程进行调试。现在我想调试main()函数,怎么办?越详细越好 非常感谢 我的代码如下 主要功能: void main() { SERVICE_TABLE_ENTRY ServiceTable[2]; ServiceTable[0].lpServiceName = "MemoryStatus"; ServiceTable[0].lpSer
void main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "MemoryStatus";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; //ServiceMain
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(ServiceTable);
}
void ServiceMain(int argc, char** argv)
{
//...some codes....
hStatus = RegisterServiceCtrlHandler("MemoryStatus",(LPHANDLER_FUNCTION)ControlHandler);
//...some codes....
//the worker loop of a service
while(ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
char buffer[10];
sprintf(buffer,"login...");
int result = WriteToLog(buffer);
if (result)
{
ReportStatus(SERVICE_STOPPED,-1);
return;
}
Sleep(SLEEP_TIME);
}
return;
}
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
WriteToLog("Monitoring stopped.");
//...Report Status to SCM code....
return;
case SERVICE_CONTROL_SHUTDOWN:
WriteToLog("Monitoring stopped.");
//...Report Status to SCM code....
return;
default:
break;
}
//...Report Status to SCM code....
return;
}
服务主要功能:
void main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "MemoryStatus";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; //ServiceMain
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(ServiceTable);
}
void ServiceMain(int argc, char** argv)
{
//...some codes....
hStatus = RegisterServiceCtrlHandler("MemoryStatus",(LPHANDLER_FUNCTION)ControlHandler);
//...some codes....
//the worker loop of a service
while(ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
char buffer[10];
sprintf(buffer,"login...");
int result = WriteToLog(buffer);
if (result)
{
ReportStatus(SERVICE_STOPPED,-1);
return;
}
Sleep(SLEEP_TIME);
}
return;
}
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
WriteToLog("Monitoring stopped.");
//...Report Status to SCM code....
return;
case SERVICE_CONTROL_SHUTDOWN:
WriteToLog("Monitoring stopped.");
//...Report Status to SCM code....
return;
default:
break;
}
//...Report Status to SCM code....
return;
}
和控制手柄功能:
void main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "MemoryStatus";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; //ServiceMain
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(ServiceTable);
}
void ServiceMain(int argc, char** argv)
{
//...some codes....
hStatus = RegisterServiceCtrlHandler("MemoryStatus",(LPHANDLER_FUNCTION)ControlHandler);
//...some codes....
//the worker loop of a service
while(ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
char buffer[10];
sprintf(buffer,"login...");
int result = WriteToLog(buffer);
if (result)
{
ReportStatus(SERVICE_STOPPED,-1);
return;
}
Sleep(SLEEP_TIME);
}
return;
}
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
WriteToLog("Monitoring stopped.");
//...Report Status to SCM code....
return;
case SERVICE_CONTROL_SHUTDOWN:
WriteToLog("Monitoring stopped.");
//...Report Status to SCM code....
return;
default:
break;
}
//...Report Status to SCM code....
return;
}
有两种不同的方法可以从windows服务开始调试它。两者都被描述 我的首选方法是使用以服务启动的远程调试器会话(您可以使用Windows调试工具中的
ntsd
)。Windows中有一种特殊机制,允许您根据进程的映像名(映像文件执行选项)劫持进程。在下面,您可以找到一个.reg文件的内容,该文件将为您设置此调试器(将路径更改为安装了调试工具的路径):
下一步是使用用户模式调试器连接到此会话:
windbg -remote "npipe:pipe=svcpipe,server=localhost"
您已经准备好调试了。请记住在重新启动计算机之前删除注册表设置,否则windows将挂起并显示黑屏:)好的,有两种方法:
首先,我们可以在代码开始时休眠服务进程。像这样:
main()
{
sleep(10);
.....
}
然后连接到服务进程,调试器将在断点位置停止,因为我们还有10秒等待
其次,我们可以在代码开头使用
\u ASSERT(FALSE)
或DebugBreak()
函数 使用GFlags.exe工具为您设置和取消设置windows注册表更容易。它很快,允许您指定所需的所有内容。只需启动它,单击“图像文件”选项卡,在图像文本框中键入图像的名称,单击选项卡,然后转到调试器行。选中“调试器”框并键入调试器的命令行,单击“确定”。不安是很容易的。取消选中Debugger的复选框。从这个答案链接的文章是一个巨大的财富。我想补充一点,您必须在更改ServicesPipeTimeout注册表值后重新启动系统,新值才能生效。