Лови исходники:
Это -- регистрация сервиса в системе
| Код | #include <stdio.h> #include <string.h> #include <windows.h> //------------------------------------------------------------------------- /* g++ -Wall -o ./install.exe ./install.cpp */ //------------------------------------------------------------------------- char infomes[0x200]; char servicedir[MAX_PATH]; //------------------------------------------------------------------------- int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev, \ LPSTR lpCmdLine,int nCmdShow \ ) { strcpy(infomes,"Service succesfull creat at path:\n"); //strcpy(servicedir,"%SystemRoot%\\System32\\service.exe"); strcpy(servicedir,"E:\\Hokum\\Program\\CPP\\testService_4\\service.exe");
SC_HANDLE scm=::OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE); if(scm) { SC_HANDLE svc=::CreateService(scm,"Test service","Test service", \ 0, \ SERVICE_WIN32_OWN_PROCESS | \ SERVICE_INTERACTIVE_PROCESS, \ SERVICE_AUTO_START, \ SERVICE_ERROR_IGNORE, \ servicedir,NULL,NULL, \ NULL,NULL,NULL \ ); if(svc) { ::CloseServiceHandle(svc); strcat(infomes,servicedir); ::MessageBox(NULL,infomes,"Install",MB_OK); } ::CloseServiceHandle(scm); } else { ::MessageBox(NULL,"Error: Can`not create service","Install",MB_OK); } return 0; }
|
Это, соответственно, снятие регистрации
| Код | #include <windows.h> //------------------------------------------------------------------------- /* g++ -Wall -o ./uninstall.exe ./uninstall.cpp */ //------------------------------------------------------------------------- INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev, \ LPSTR lpCmdLine,int nCmdShow \ ) { SC_HANDLE scm=::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if(scm) { SC_HANDLE svc=::OpenService(scm,"Test service", \ STANDARD_RIGHTS_REQUIRED \ ); ::DeleteService(svc); if(svc) { ::CloseServiceHandle(svc); ::MessageBox(NULL,"Succefull","Uninstall",MB_OK); } ::CloseServiceHandle(scm); } else { ::MessageBox(NULL,"Error: Can`not uninstall service","Uninstall",MB_OK); } return 0; }
|
Это -- исходник службы, я его сильно прокомментировал
| Код | #include <stdio.h> #include <string.h> #include <windows.h> #include "service.h" //------------------------------------------------------------------------- /* Упреждающее объявление WinMain */ extern "C" INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev, \ LPSTR lpCmdLine,int nCmdShow \ ); //------------------------------------------------------------------------- /* Управляющее событие */ HANDLE hControlEvent; /**/ HMODULE g_module=NULL; /* Текущий статус сервиса */ SERVICE_STATUS ss; /* Handle для структуры статуса */ SERVICE_STATUS_HANDLE ssh; /* Объединяем в одну структуру для возможности передачи указателя на неё */ struct SsSsh { SERVICE_STATUS ss; SERVICE_STATUS_HANDLE ssh; }; //------------------------------------------------------------------------- VOID SetSomeServiceStatus(DWORD dwCurrentState, \ DWORD dwWin32ExitCode, \ DWORD dwWaitHint, \ SsSsh* pSsSsh \ ) {/* Устанавливаем статус сервиса */ /* Инициализация контрольной точки */ static DWORD dwCheckPoint=1; /* Забираем данные о состоянии сервиса */ SERVICE_STATUS ss=(*(pSsSsh)).ss; SERVICE_STATUS_HANDLE ssh=(*(pSsSsh)).ssh; /* Если сервер запускается */ if(dwCurrentState == SERVICE_START_PENDING) ss.dwControlsAccepted=0; else/* Любой другой случай */ ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
ss.dwCurrentState=dwCurrentState; ss.dwWin32ExitCode=dwWin32ExitCode; ss.dwWaitHint=dwWaitHint; /* Если сервис закончил запуск или остановку, сброс контрольной точки */ if( (dwCurrentState == SERVICE_RUNNING) || \ (dwCurrentState == SERVICE_STOPPED) \ ) ss.dwCheckPoint=0; else/* Иначе -- инкрементируем контрольную точку */ ss.dwCheckPoint=dwCheckPoint++; /* И отдаём изменённые данные диспетчеру сервисов */ ::SetServiceStatus(ssh,&ss); } //------------------------------------------------------------------------- DWORD WINAPI HandlerEx(DWORD dwControl,DWORD dwEventType, \ LPVOID lpEventData,LPVOID lpContext \ ) {/* Обработчик сигналов управления сервисом */ /* Принимаем данные о состоянии сервиса */ SsSsh ssssh=*((SsSsh*)lpContext); switch(dwControl) { /* Если система выключается */ case SERVICE_CONTROL_SHUTDOWN: /* Или останавливается сервис */ case SERVICE_CONTROL_STOP: { /* Статус сервиса -- "В процессе остановки" */ SetSomeServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,&ssssh); /* Останавливаем поток */ ::SetEvent(hControlEvent); while(::WaitForSingleObject(hControlEvent,0) == WAIT_OBJECT_0) { Sleep(0); } /* Статус сервиса -- "Остановлен" */ SetSomeServiceStatus(SERVICE_STOPPED,NO_ERROR,0,&ssssh); break; } case SERVICE_CONTROL_INTERROGATE: {/* Опрос текущего состояния сервиса */ SetSomeServiceStatus(ssssh.ss.dwCurrentState,NO_ERROR,0,&ssssh); break; } default: { SetSomeServiceStatus(ssssh.ss.dwCurrentState,NO_ERROR,0,&ssssh); break; } } return 0; } //------------------------------------------------------------------------- VOID WINAPI ServiceMain(DWORD dwArgc,LPTSTR* lpszArgv) { SsSsh ssssh; SERVICE_STATUS ss; /* Регистрируем функцию-обработчик сигналов к сервису, передаём ей имя сервиса, собственно, указатель на обработчик и контекст */ SERVICE_STATUS_HANDLE ssh=RegisterServiceCtrlHandlerEx(WebPrice, \ &HandlerEx, \ (VOID*)&ssssh \ ); /* Сервисом будет обычный процесс */ ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS; /* Начальное состояние -- в процессе запуска */ ss.dwCurrentState=SERVICE_START_PENDING;/// /* Отслеживает остановку и выключение системы */ ss.dwControlsAccepted=SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; /* Не сообщаем об ошибках */ ss.dwWin32ExitCode=NO_ERROR; /**/ ss.dwServiceSpecificExitCode=0;/// /* Начинаем отсчёт запуска */ ss.dwCheckPoint=1;//0 /* Если через 5 сек. dwCheckPoint не инкрементируется -- проблемы */ ss.dwWaitHint=5000;//0 /* Собираем данные в кучу */ ssssh.ss=ss; ssssh.ssh=ssh; /**/ SetSomeServiceStatus(SERVICE_START_PENDING,NO_ERROR,4000,&ssssh); FILE* file=fopen("E:\\ZZZ.txt","a"); if(file == NULL) return; SetSomeServiceStatus(SERVICE_RUNNING,NO_ERROR,0,&ssssh); // main program code while(::WaitForSingleObject(hControlEvent,0) != WAIT_OBJECT_0) { fwrite("test\n",1,5,file); fflush(file); Sleep(30000); } fwrite("\0",1,2,file); fflush(file); fclose(file); ::ResetEvent(hControlEvent); ::CloseHandle(hControlEvent); return; } //------------------------------------------------------------------------- INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev, \ LPSTR lpCmdLine,int nCmdShow \ ) { /* Если не удалось создать управляющее событие -- огорчение */ if((hControlEvent=::CreateEvent(NULL,TRUE,FALSE,NULL)) == NULL) return -1; SERVICE_TABLE_ENTRY DispatcherTable[]= {/* Описание запускаемых сервисов */ {WebPrice,(LPSERVICE_MAIN_FUNCTION)ServiceMain}, {NULL,NULL} }; /* Запуск сервисов */ ::StartServiceCtrlDispatcher(DispatcherTable); return 0; }
|
А это -- заголовочный файл к нему
| Код | #ifndef SERVICE_H_20070910_1251 #define SERVICE_H_20070910_1251
#define WebPrice "WebPrice" extern DWORD WINAPI EntryPoint(LPVOID lpParam); extern HMODULE g_module;
#endif
|
ВотЪ, Makefile, на всякий случай...
| Код | REMOVE = rm -f SRCINSTALL = install SRCUNINSTALL = uninstall SRCMAIN = service SRCMAINHEADER = service OUTINSTALL = $(SRCINSTALL) OUTUNINSTALL = $(SRCUNINSTALL) OUTMAIN = service
$(OUTINSTALL) : $(SRCINSTALL).o g++ -o $(OUTINSTALL) $(SRCINSTALL).o $(SRCINSTALL).o : $(SRCINSTALL).cpp g++ -c -Os -Wall $(SRCINSTALL).cpp strip --strip-debug $(SRCINSTALL).o $(OUTUNINSTALL) : $(SRCUNINSTALL).o g++ -o $(OUTUNINSTALL) $(SRCUNINSTALL).o $(SRCUNINSTALL).o : $(SRCUNINSTALL).cpp g++ -c -Os -Wall $(SRCUNINSTALL).cpp strip --strip-debug $(SRCUNINSTALL).o $(OUTMAIN) : $(SRCMAIN).o g++ -o $(OUTMAIN) $(SRCMAIN).o $(SRCMAIN).o : $(SRCMAIN).cpp $(SRCMAINHEADER).h g++ -c -Os -Wall $(SRCMAIN).cpp strip --strip-debug $(SRCMAIN).o
exe_install : $(MAKE) $(OUTINSTALL) exe_uninstall : $(MAKE) $(OUTUNINSTALL) exe_main : $(MAKE) $(OUTMAIN) clean_install : $(REMOVE) $(OUTINSTALL).exe $(REMOVE) $(SRCINSTALL).o clean_uninstall : $(REMOVE) $(OUTUNINSTALL).exe $(REMOVE) $(SRCUNINSTALL).o clean_main : $(REMOVE) $(OUTMAIN).exe $(REMOVE) $(SRCMAIN).o clean : $(REMOVE) $(wildcard *.exe) $(REMOVE) $(wildcard *.o) help : @echo clean exe_install exe_uninstall exe_main ALL : clean exe_install exe_uninstall exe_main
|
Тут несколько коряво всё сделано, конечно, зато работает! |