Writing a Control Handler Function
The MyServiceCtrlHandler function in the following example is the
Handler function. When this function is called by the dispatcher thread, it handles
the control code passed in the
Opcode parameter and then calls the
SetServiceStatus function to update the service's status. Every time a
Handler function receives a control code, it is appropriate to return status with a
call to
SetServiceStatus regardless of whether the service acts on the control.
When the pause control is received, MyServiceCtrlHandler simply sets the
dwCurrentState field in the SERVICE_STATUS structure to SERVICE_PAUSED. Likewise, when the
continue control is received, the state is set to SERVICE_RUNNING. Therefore,
MyServiceCtrlHandler is not a good example of how to handle the pause and
continue controls. Because MyServiceCtrlHandler is a template for a
Handler function, code for the pause and continue controls is included for
completeness. A service that supports either the pause or continue control should handle
these controls in a way that makes sense. Many services support neither the
pause or continue control. If the service indicates that it does not support pause
or continue with the
dwControlsAccepted parameter, then the SCM will not send pause or continue controls to the
service's
Handler function.
To output debugging information, MyServiceCtrlHandler calls SvcDebugOut. The
source code SvcDebugOut is listed in
Writing a Service Program's main Function.
VOID MyServiceCtrlHandler (DWORD Opcode)
{
DWORD status;
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
// Do whatever it takes to pause here.
MyServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
// Do whatever it takes to continue here.
MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
// Do whatever it takes to stop here.
MyServiceStatus.dwWin32ExitCode = 0;
MyServiceStatus.dwCurrentState = SERVICE_STOPPED_PENDING;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus (MyServiceStatusHandle,
&MyServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [MY_SERVICE] SetServiceStatus error
%ld\n",status);
}
SvcDebugOut(" [MY_SERVICE] Leaving MyService \n",0);
return;
case SERVICE_CONTROL_INTERROGATE:
// Fall through to send current status.
break;
default:
SvcDebugOut(" [MY_SERVICE] Unrecognized opcode %ld\n",
Opcode);
}
// Send current status.
if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [MY_SERVICE] SetServiceStatus error
%ld\n",status);
}
return;
}
- Software for developers
-
Delphi Components
.Net Components
Software for Android Developers
- More information resources
-
MegaDetailed.Net
Unix Manual Pages
Delphi Examples
- Databases for Amazon shops developers
-
Amazon Categories Database
Browse Nodes Database