Извините за длину образца, но чтобы получить все необходимые компоненты услуги, она должна быть такой длинной.
Используя помощь других здесь, мне удалось получить сервис, который запускается чисто, но теперь он не остановится чисто.
При первой попытке быстро остановить его выдает ошибку
Could not stop the My service service on local computer
The service did not return an error. This could be an internal Windows error or an internal service error
If the problem persists, contact your system administrator
и служба продолжает работать, даже после 5 минут, которые занимает цикл ожидания.
При второй попытке остановить диспетчер задач показывает, что процесс останавливается немедленно, но Service Manager очень долго выдает ошибку
Could not stop the My service service on local computer
Error 1053: The service did not respond to the start or control request in a timely fashion.
А вот и исходный код
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <windows.h>
#include <winsvc.h>
#include <time.h>
#define MY_SVC_NAME "My service"
#define THE_PROG "\"C:\\Program Files\\My software\\bin\\The Prog.exe\""
#define SLEEP_TIME 300000
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
void WINAPI ServiceMain(DWORD argc, LPSTR argv);
void WINAPI ControlHandler(DWORD request);
void InitService();
int cont_running = 1;
DWORD WINAPI ServiceHandlerProc(DWORD ControlCode, DWORD a, void *b, void *c)
{
switch (ControlCode) {
case SERVICE_CONTROL_STOP :
cont_running = 0;
ServiceStatus.dwCheckPoint=0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
ServiceStatus.dwWaitHint =2000;
SetServiceStatus (hStatus, &ServiceStatus);
Sleep(1000);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
break;
case SERVICE_CONTROL_SHUTDOWN :
cont_running = 0;
ServiceStatus.dwCheckPoint=0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
ServiceStatus.dwWaitHint =2000;
SetServiceStatus (hStatus, &ServiceStatus);
Sleep(1000);
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
break;
}
return 0;
}
void WINAPI ServiceMain(DWORD argc, LPSTR argv)
{
int hServiceStatus;
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 = RegisterServiceCtrlHandlerEx(MY_SVC_NAME, ServiceHandlerProc,0);
/*
if (hStatus == (SERVICE_STATUS_HANDLE)0) {
return;
}
*/
Sleep(1000);
ServiceStatus.dwCheckPoint=0;
ServiceStatus.dwWaitHint=0;
ServiceStatus.dwCurrentState=SERVICE_RUNNING;
SetServiceStatus( hServiceStatus, &ServiceStatus);
InitService();
return;
}
void InitService()
{
cont_running=1;
do {
system(THE_PROG);
Sleep(SLEEP_TIME);
} while (cont_running);
}
int main(int argc, char *argv[], char *envp[])
{
SERVICE_TABLE_ENTRY ServiceStartTable[2];
ServiceStartTable[0].lpServiceName = MY_SVC_NAME;
ServiceStartTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceStartTable[1].lpServiceName = NULL;
ServiceStartTable[1].lpServiceProc = NULL;
if (!StartServiceCtrlDispatcher(ServiceStartTable))
{
DWORD err = GetLastError();
if (err == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
return 1;
}
return 0;
}
Я безуспешно ссылался на следующие документы
http://msdn.microsoft.com/en-us/library/ms809975.aspx
Справочное руководство по обслуживанию LUA