Да, этот пример не особенно хорошо написан.Основной цикл службы лучше записать (концептуально) как:
// 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
- глобальныйпеременная.
На практике (во избежание зацикливания) служба, вероятно, обычно бездействует, ожидая какого-то ожидаемого объекта, чтобы что-то сделать.Давайте представим, ради аргумента, это HANDLE, называемый, скажем, 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 - смешанный беспорядок.