Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用c而不是c调试windows服务启动代码#_C_Windows_Debugging_Windows Services_Startup - Fatal编程技术网

如何用c而不是c调试windows服务启动代码#

如何用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

每个人

我想知道如何用C调试windows服务启动代码。在C中有几个类似的问题,但它们不是我需要的。 到目前为止,我只能附加到进程进行调试。现在我想调试main()函数,怎么办?越详细越好

非常感谢

我的代码如下

主要功能:

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注册表值后重新启动系统,新值才能生效。