In order to create a windows serivice program, a program must have certain content inside to register and respond to actions. Also, it must be registered to the system through the program sc
at shell or through editing the registry table which both need adminstrator permission.
In the program:
#Declare three global varible. The name is not important.
SERVICE_TABLE_ENTRY entryTable[2];
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
#declare 2 global functions as follow which one will be called when the service start and work as the main function of the service in another process and another will be called when there is a control signal like start or restart was issued by the system or users. The name of them is not important.
void WINAPI ctrlHandler(DWORD request);
void WINAPI serviceMain(int argc, char**argv);
#Fill in the created array of the struct SERVICE_TABLE_ENTRY
contains two elements in that service information in the first one and put all nulls in the second as follow. Then, use StartServiceCtrlDispatcher(entryTable);
to register the service. This step have to be done during founction main
.
void initEntryTable(SERVICE_TABLE_ENTRY &templateEnteyTable){
entryTable[0].lpServiceName = templateEnteyTable.lpServiceName;
entryTable[0].lpServiceProc = templateEnteyTable.lpServiceProc;
entryTable[1].lpServiceName = NULL;
entryTable[1].lpServiceProc = NULL;
StartServiceCtrlDispatcher(entryTable);
}
I use these codes to initialize a entry table.
serviceT.lpServiceName = TEXT("testservice");
serviceT.lpServiceProc = (LPSERVICE_MAIN_FUNCTION)serviceMain;
initEntryTable(serviceT);
#Now the void WINAPI serviceMain(int argc, char**argv);
should contains code like the following to illustrate the property of itself by giving certain value of the variables inside the struct ServiceStatus. Then, register the service and get the handle of it with hStatus = ::RegisterServiceCtrlHandlerW(TEXT("testservice"), ctrlHandler);
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;/*This is the state of this service and need to be changed actively.*/
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP; /*This is the types of command your service could recieve*/
ServiceStatus.dwWin32ExitCode = 0;/*I am still learning this part, leave it 0*/
ServiceStatus.dwServiceSpecificExitCode = 0;/*I am still learning this part, leave it 0*/
ServiceStatus.dwCheckPoint = 0;/*I am still learning this part, leave it 0*/
ServiceStatus.dwWaitHint = 0;/*I am still learning this part, leave it 0*/
hStatus = ::RegisterServiceCtrlHandlerW(TEXT("testservice"), ctrlHandler);
#Since the serviceMain()
founction takes controll of the service status, the state of the service must be change to ServiceStatus.dwCurrentState = SERVICE_RUNNING;
and report to the system with SetServiceStatus
once it done with initialization or the system will wrongly recognize the service as “going wrong” and get a error of “failed to start, service is not responding”.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(hStatus, &ServiceStatus);
#For the void WINAPI ctrlHandler(DWORD request)
, it deals with requests like shutdown and the request will be sent as parameter.
#The final step is to register the service officially to the system through sc
or the registry table. I use the first step because it’s easier.
Manually: Enter system shell, use sc create testservice binPath="C:\path\to\file.exe"
to create a new service. ==(There is a space after all the =
symbols which is necessary)==
To configure it like make the service start up on boot, either sc config testservice [configuration]
or sc create testservice [configuration works]
.
InCode: I use the following code the do the job.
std::string filename(argv[0]);
string mycommand = (std::string)”sc create testservice binPath= \””+filename+”\””+” start= auto”;
const char *c = mycommand.data();
std::cout << “Execute: “ << mycommand << “?” << std::endl<
#Now the service should be done and should be shown in the service control manager.
2017/2/9 13:06