Windows - Vlastní služba v C++
Moje jednoduchá služba v C++ spouštějící BATový skript těsně po startu počítače (ještě pod přihlašovací obrazovkou), těsně před vypnutím počítače a jeden ještě každou hodinu. Výjmenčné spíše tím, že běží pod uživatelem SYSTEM, tedy účtem NT jádra.
#include <stdio.h> #include <windows.h> #include <winsvc.h> #include <tchar.h> #define SVCNAME TEXT("JKbat") #define SVCDESC TEXT("JKbat") SERVICE_STATUS_HANDLE g_ServiceStatusHandle; HANDLE g_StopEvent; DWORD g_CurrentState = 0; bool g_SystemShutdown = false; void WINAPI ServiceMain(DWORD argc, LPTSTR *argv); DWORD WINAPI HandlerEx(DWORD control, DWORD eventType, void *eventData, void *context); void ReportStatus(DWORD state); void install(); void uninstall(); void help(char *thiscmd); // Standard console application entry point. int main(int argc, char **argv) { SERVICE_TABLE_ENTRY serviceTable[] = { { _T(""), &ServiceMain }, { NULL, NULL } }; if (StartServiceCtrlDispatcher(serviceTable)){ return 0; }else if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT){ if(argc>1){ if(strcmp(argv[1],"install")==0){ install(); }else if(strcmp(argv[1],"uninstall")==0){ uninstall(); }else{ help(argv[0]); } }else{ help(argv[0]); } return 0; }else{ return -2; } } // Main function to be executed as entire service code. void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) { g_ServiceStatusHandle = RegisterServiceCtrlHandlerEx(_T("SERVICE NAME"), &HandlerEx, NULL); ReportStatus(SERVICE_START_PENDING); g_StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // Po zapnuti: system("C:\\BAT\\start.bat"); ReportStatus(SERVICE_RUNNING); while (WaitForSingleObject(g_StopEvent,3600000)!=WAIT_OBJECT_0){ // Kazdou hodinu: system("C:\\BAT\\hodina.bat"); } ReportStatus(SERVICE_STOP_PENDING); // Pred vypnutim: system("C:\\BAT\\stop.bat"); CloseHandle(g_StopEvent); ReportStatus(SERVICE_STOPPED); } void ReportStatus(DWORD state) { g_CurrentState = state; SERVICE_STATUS serviceStatus = { SERVICE_WIN32_OWN_PROCESS, g_CurrentState, state == SERVICE_START_PENDING ? 0 : SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN, NO_ERROR, 0, 0, 0, }; SetServiceStatus(g_ServiceStatusHandle, &serviceStatus); } void ReportProgressStatus(DWORD state, DWORD checkPoint, DWORD waitHint) { g_CurrentState = state; SERVICE_STATUS serviceStatus = { SERVICE_WIN32_OWN_PROCESS, g_CurrentState, state == SERVICE_START_PENDING ? 0 : SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN, NO_ERROR, 0, checkPoint, waitHint, }; SetServiceStatus(g_ServiceStatusHandle, &serviceStatus); } void ReportErrorStatus(DWORD errorCode) { g_CurrentState = SERVICE_STOPPED; SERVICE_STATUS serviceStatus = { SERVICE_WIN32_OWN_PROCESS, g_CurrentState, 0, ERROR_SERVICE_SPECIFIC_ERROR, errorCode, 0, 0, }; SetServiceStatus(g_ServiceStatusHandle, &serviceStatus); } // Handler for service control events. DWORD WINAPI HandlerEx(DWORD control, DWORD eventType, void *eventData, void *context) { switch (control) { // Entrie system is shutting down. case SERVICE_CONTROL_SHUTDOWN: g_SystemShutdown = true; // continue... // Service is being stopped. case SERVICE_CONTROL_STOP: ReportStatus(SERVICE_STOP_PENDING); SetEvent(g_StopEvent); break; // Ignoring all other events, but we must always report service status. default: ReportStatus(g_CurrentState); break; } return NO_ERROR; } void install(){ SC_HANDLE schSCManager; SC_HANDLE schService; TCHAR szPath[MAX_PATH]; if( !GetModuleFileName( NULL, szPath, MAX_PATH ) ) { printf("Cannot install service (%d)\n", GetLastError()); return; } schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("OpenSCManager failed (%d)\n", GetLastError()); printf("Spoustite tento prikaz jako spravce?\n"); return; } schService = CreateService( schSCManager, // SCM database SVCNAME, // name of service SVCDESC, // service name to display SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type szPath, // path to service's binary NULL, // no load ordering group NULL, // no tag identifier "Tcpip\0lmhosts\0", // dependencies NULL, // LocalSystem account NULL); // no password if (schService == NULL) { printf("CreateService failed (%d)\n", GetLastError()); printf("Treba uz je sluzba nainstalovana?\n"); CloseServiceHandle(schSCManager); return; } else printf("Service installed successfully\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } void uninstall(){ SC_HANDLE schSCManager; SC_HANDLE schService; SERVICE_STATUS ssStatus; schSCManager = OpenSCManager( NULL, // local computer NULL, // ServicesActive database SC_MANAGER_ALL_ACCESS); // full access rights if (NULL == schSCManager) { printf("OpenSCManager failed (%d)\n", GetLastError()); printf("Spoustite tento prikaz jako spravce?\n"); return; } // Get a handle to the service. schService = OpenService( schSCManager, // SCM database SVCNAME, // name of service DELETE); // need delete access if (schService == NULL) { printf("OpenService failed (%d)\n", GetLastError()); printf("Treba neni sluzba nainstalovana?\n"); CloseServiceHandle(schSCManager); return; } if (! DeleteService(schService) ) { printf("DeleteService failed (%d)\n", GetLastError()); printf("Treba neni sluzba nainstalovana?\n"); } else printf("Service deleted successfully\n"); CloseServiceHandle(schService); CloseServiceHandle(schSCManager); } void help(char *thiscmd){ printf("\nToto je program, ktery se instaluje jako sluzba a\n"); printf("pri startu, vypinani pocitace a kazdou hodinu\n"); printf("spousti prislusne skripty z C:\\BAT\n"); printf("(start.bat;stop.bat;hodina.bat)\n"); printf("Moznosti:\n"); printf(" %s install Nainstaluje sluzbu\n",thiscmd); printf(" %s uninstall Odinstaluje sluzbu\n",thiscmd); printf(" net start %s Spusti sluzbu\n",SVCNAME); printf(" net stop %s Zastavi sluzbu\n",SVCNAME); printf("\nAutor: Jan Kalina\n"); }
Autor: ![]() Vydáno: 19.6.2011 13:48 Přečteno: 1993x Hodnocení: neohodnoceno Vaše hodnocení: |
MSDN: CreateService |
Komentáře
Nebyly přidány žádné komentáře.