The main function of a service program calls the StartServiceCtrlDispatcher function to connect to the SCM and start the control dispatcher thread. The dispatcher thread loops, waiting for incoming control requests for the services specified in the dispatch table. This thread does not return until there is an error or all of the services in the process have terminated. When all services in a process have terminated, the SCM sends a control request to the dispatcher thread telling it to shut down. The thread can then return from the StartServiceCtrlDispatcher call and the process can terminate.
The following example is a service process that supports only one service. It takes two parameters: a string that can contain one formatted output character and a numeric value to be used as the formatted character. The SvcDebugOut
function prints informational messages and errors to the debugger.
SERVICE_STATUS MyServiceStatus;
SERVICE_STATUS_HANDLE MyServiceStatusHandle;
VOID MyServiceStart (DWORD argc, LPTSTR *argv);
VOID MyServiceCtrlHandler (DWORD opcode);
DWORD MyServiceInitialization (DWORD argc, LPTSTR *argv,
DWORD *specificError);
VOID _CRTAPI1 main( )
{
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ TEXT("MyService"), MyServiceStart },
{ NULL, NULL }
};
if (!StartServiceCtrlDispatcher( DispatchTable))
{
SvcDebugOut(" [MY_SERVICE] StartServiceCtrlDispatcher error =
%d\n", GetLastError());
}
}
VOID SvcDebugOut(LPSTR String, DWORD Status)
{
CHAR Buffer[1024];
if (strlen(String) < 1000)
{
sprintf(Buffer, String, Status);
OutputDebugStringA(Buffer);
}
}
If your service program supports multiple services, the implementation of the main
function will differ slightly. The names of the additional services should be added to the dispatch table so they can be monitored by the dispatcher thread.