我应该在服务模板中的什么地方添加自己的代码?
Where should I add my own code in the service template?
Microsoft 提供了一个 complete service sample to start with writing Windows services. However, I do not understand the following part from 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);
...当适当的事件被触发时,服务将无法停止,是吗?
这个模板有缺陷吗?我怎样才能让我的服务等待外部触发而不让它无法停止调用?
是的,那个例子写得不是特别好。服务的主循环最好(概念上)写成:
// 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
的 HANDLE,通过 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 样本是一团糟。
Microsoft 提供了一个 complete service sample to start with writing Windows services. However, I do not understand the following part from 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);
...当适当的事件被触发时,服务将无法停止,是吗?
这个模板有缺陷吗?我怎样才能让我的服务等待外部触发而不让它无法停止调用?
是的,那个例子写得不是特别好。服务的主循环最好(概念上)写成:
// 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
的 HANDLE,通过 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 样本是一团糟。