我应该在服务模板中的什么位置添加自己的代码?

时间:2018-07-06 08:15:18

标签: c++ windows service windows-services

Microsoft提供了complete service sample,以开始编写Windows服务。但是,我不了解this file的以下内容:

ReportSvcStatus( SERVICE_RUNNING, NO_ERROR, 0 );

// TO_DO: Perform work until service stops.

while(1)
{
    // Check whether to stop the service.

    WaitForSingleObject(ghSvcStopEvent, INFINITE);

    ReportSvcStatus( SERVICE_STOPPED, NO_ERROR, 0 );
    return;
}

我不明白包含return语句的无限循环的意义。它不会达到目的吗?

似乎鼓励在while循环之前编写服务内容,但是如果没有到达以下行,则应该这样做:

WaitForSingleObject(ghSvcStopEvent, INFINITE);

...触发适当的事件后,服务将无法停止,对吗?

此模板是否有缺陷?如何使我的服务等待外部触发而不会停止呼叫?

1 个答案:

答案 0 :(得分:2)

是的,该示例编写得不是特别好。服务的主循环最好从概念上写为:

// Main processing loop
while (!quit)
    do_work ();

ReportSvcStatus (SERVICE_STOPPED, NO_ERROR, 0);
return;

在服务的控制处理程序中,您将拥有:

// CtrlHandler callback
DWORD WINAPI CtrlHandler (DWORD dwControl, DWORD  dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
    ...
    if (dwControl == SERVICE_CONTROL_STOP)
        quit = true;
    return NO_ERROR;
}

quit是全局变量。

在实践中(为了避免繁忙的循环),服务通常可能会在等待某种可等待对象的过程中闲坐。让我们想象一下,为了争辩,这是一个称为ghWakeupEvent的句柄,它是通过CreateEvent()创建的,并再次存储在全局变量中。

然后,代码变为:

// Main processing loop
while (1)
{
    WaitForSingleObject (ghWakeupEvent, INFINITE);
    if (quit)
    {
        ReportSvcStatus (SERVICE_STOPPED, NO_ERROR, 0);
        return;
    }

    if (something_to_do)
        do_work ();
}

// CtrlHandler callback
DWORD WINAPI CtrlHandler (DWORD dwControl, DWORD  dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
    ...
    if (dwControl == SERVICE_CONTROL_STOP)
    {
        quit = true;    // do this first!!
        SetEvent (ghWakeupEvent);
    }

    return NO_ERROR;
}

注意:不需要(或指向)ghSvcStopEvent。 MSDN示例是一团糟。