Kategorie: Obecné

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.

Stáhnout

#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");
}

Komentáře


Nebyly přidány žádné komentáře.