Days ago, my colleague wanted to have his program written as a window service, and has no clue doing it. I searched online and came across some info, and then compiled the following program.
/*
* Service.c
*
*/
#include <windows.h>
#include <stdio.h>
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
int WriteToLog(char* str)
{
FILE* log;
log = fopen("C:\\CowService\\log.txt", "a+");
fprintf(log, "%s\n", str);
fclose(log);
return 0;
}
int InitService()
{
int result;
result = WriteToLog("Service Started.");
return(result);
}
// Handler to be registered and called when user interact with the service. (inside the "Windows Service")
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
WriteToLog("Service Closed");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
WriteToLog("Service Closed");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
default:
break;
}
SetServiceStatus (hStatus, &ServiceStatus);
return;
}
void ServiceMain(int argc, char** argv)
{
int error;
// Initialize and set the state of the service to be "Pending"
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;
hStatus = RegisterServiceCtrlHandler("CowService", (LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
return;
}
error = InitService();
if (error)
{
// Error, set the service state to "Stopped" and return
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
// Set the service state to be "Running"
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hStatus, &ServiceStatus);
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
// while the service is on, do whatever you wish here.
int result = WriteToLog("Service is Running\n");
Sleep(2000);
}
return;
}
int main()
{
// Create service table entry to be registered
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "CowService";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
// Setting the entry NULL to indicate it's the end of the service table entry
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}
The code is straightforward, and comments should have spoken for itself.
However, to have the service program working, you have to register it with the “Windows Service” by issuing
// sc create <servcie name> bin_path= <location to the service program>
sc create CowService bin_path= C:\CowService.exe