Creating a Windows service is fairly simple. You start by writing you
main() function as you would normally. In the
main() function you have to call
StartServiceCrtlDispatcher(). The programm has to make this call at least 30 seconds after it has launched. Otherwise Windows will assume the service failed to start up. So the simplest main() function for a service will look something like this:
int main(int argc, char **argv) {
SERVICE_TABLE_ENTRY serviceTable[2];
serviceTable[0].lpServiceName = "ServiceTest";
serviceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION) ServiceMain;
serviceTable[1].lpServiceName = NULL;
serviceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(serviceTable);
}
StartServiceCrtlDispatcher() takes an array of
SERVICE_TABLE_ENTRYs. Each defines the name and callback function of one service it should start. The callback function is run in its own thread and
StartServiceCrtlDispatcher() will only return after all services it has started have been stopped.
As the name indicates, the callback function of the service is the real main function of the service. Here the service should do whatever it is supposed to do. In order to by managed by the Services interface of Windows the service has to implement a callback to a control handler with the
RegisterServiceCrtlHandler() function. The callback is invoked every time the service should change its state (Stop for example).
The service should use the
SetServiceStatus() function to report its current status to the system. The following code can be used as a skeleton for your own service.
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hServiceStatus;
// Control handler function callback
void ControlHandler(DWORD request)
{
switch(request) {
case SERVICE_CONTROL_STOP:
// Service has been stopped
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hServiceStatus, &ServiceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hServiceStatus, &ServiceStatus);
return;
default:
break;
}
// Report current status
SetServiceStatus (ServiceStatusHandle, &ServiceStatus);
}
// Service main function callback
void ServiceMain(int argc, char **argv) {
int count = 0;
int result;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hServiceStatus= RegisterServiceCtrlHandler(
"ServiceTest",
(LPHANDLER_FUNCTION) ControlHandler);
if (hServiceStatus == (SERVICE_STATUS_HANDLE) 0) {
// Registering Control Handler failed
return;
}
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hServiceStatus, &ServiceStatus);
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING) {
// Do you important service stuff here
Sleep(5000);
}
}
This service will run as long as its state is
SERVICE_RUNNING. Once the state changes the
ServiceMain function will return and the service will terminate.
Visit these links for more examples and explanations: