Сервис И Месседжы

Тема в разделе "MS Visual C++", создана пользователем bearpaw, 26 сен 2013.

  1. bearpaw

    bearpaw Member

    Регистрация:
    15 окт 2010
    Сообщения:
    8
    Симпатии:
    0
    Доброго времени суток, уважаемые форумчане!

    Занимаюсь созданием сервиса для Windows, который должен отлавливать один единственный месседж от ОС - WM_TIMECHANGE и писать это в лог-файл (в дальнейшем - писать на syslog-сервер).
    Заготовка сервиса создана, уже умеет запускатся/останавливатся.
    Единственное что - никак не могу сообразить как обрабатывать сообщения, не имея при этом окна.

    Быть может, кто-либо подскажет как сие реализовать? Желательно, куском кода или пошаговым описанием процесса. Короче, как для человека, изрядно подзабывшего Cpp... :)

    <div class="sp-wrap"><div class="sp-head-wrap"><div class="sp-head folded clickable">Выглядит заготовка так :</div></div><div class="sp-body"><div class="sp-content">
    Код (C++):
    #include <stdio.h>
    #include "stdafx.h"
    #include <Windows.h>
    #include <time.h>
    #include <iomanip>

    DWORD WINAPI HandlerEx(DWORD control, DWORD eventType, void *eventData, void *context);
    void ReportErrorStatus(DWORD errorCode);
    void ReportProgressStatus(DWORD state, DWORD checkPoint, DWORD waitHint);
    void ReportStatus(DWORD state);
    void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
    void addLogMessage(const TCHAR* t, ...);

    int StartService();
    int RemoveService();
    void InstallService();

    LPTSTR svcName;
    LPTSTR svcPath;

    time_t curTime;

    SERVICE_STATUS_HANDLE g_ServiceStatusHandle;
    HANDLE g_StopEvent;
    DWORD g_CurrentState = 0;
    bool g_SystemShutdown = false;

    int _tmain(int argc, wchar_t* argv[])
    {
    time(&curTime);

    svcName = LPTSTR(L"TimeWatcher");
    svcPath = LPTSTR(argv[0]);

    TCHAR buf[64] = {0};
    wsprintf(buf, L"Trying to %s service\n", argv[argc - 1]);
    addLogMessage(buf);

    if (wcscmp(argv[argc-1], _T("install")) == 0)
    {
    InstallService();
    }
    else if (wcscmp(argv[argc-1], _T("remove")) == 0)
    {
    RemoveService();
    }
    else if (wcscmp(argv[argc-1], _T("start")) == 0)
    {
    StartService();
    }
    else if (wcscmp(argv[argc-1], _T("service")) == 0)
    {

    SERVICE_TABLE_ENTRY serviceTable[] = {
    { _T(""), &ServiceMain },
    { NULL, NULL }
    };
    if (StartServiceCtrlDispatcher(serviceTable))
    return 0;
    else if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
    return -1; // Program not started as a service.
    else
    return -2; // Other error.
    }
    return 0;
    }

    // Main function to be executed as entire service code.
    void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
    {
    g_ServiceStatusHandle = RegisterServiceCtrlHandlerEx(svcName, &HandlerEx, NULL);

    time(&curTime);

    ReportStatus(SERVICE_START_PENDING);
    g_StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

    ReportStatus(SERVICE_RUNNING);

    while (WaitForSingleObject(g_StopEvent, 3000) != WAIT_OBJECT_0)
    {
    // add something here
    }

    ReportStatus(SERVICE_STOP_PENDING);
    addLogMessage(TEXT("Service shutdown! \n"));

    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)
    {
    // 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 InstallService()
    {
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    TCHAR szPath[MAX_PATH + 9];
    TCHAR tCantInst[] = L"Cannot install service (%d)";

    if (!GetModuleFileName(NULL, szPath, MAX_PATH))
    {
    addLogMessage(tCantInst);
    return;
    }
    wcscat_s(szPath,MAX_PATH+9,L" service");

    schSCManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
    if (!schSCManager)
    {
    addLogMessage(tCantInst);
    return;
    }

    schService=CreateService(schSCManager, svcName, svcName,
    SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START,
    SERVICE_ERROR_NORMAL, szPath, 0, 0, 0, 0, 0);
    if (!schService)
    {
    addLogMessage(tCantInst);
    CloseServiceHandle(schSCManager);
    return;
    }
    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
    time(&curTime);
    addLogMessage(L"Service Installed!\n");
    }

    int RemoveService()
    {
    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!hSCManager)
    {
    addLogMessage(TEXT("Error: Can't open Service Control Manager\n"));
    return -1;
    }
    SC_HANDLE hService = OpenService(hSCManager, svcName, SERVICE_STOP | DELETE);
    if (!hService)
    {
    addLogMessage(TEXT("Error: Can't remove service\n"));
    CloseServiceHandle(hSCManager);
    return -1;
    }

    DeleteService(hService);
    CloseServiceHandle(hService);
    CloseServiceHandle(hSCManager);
    addLogMessage(TEXT("Success remove service!\n"));
    return 0;
    }

    int StartService()
    {
    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    SC_HANDLE hService = OpenService(hSCManager, svcName, SERVICE_START);
    if (!StartService(hService, 0, NULL))
    {
    CloseServiceHandle(hSCManager);
    addLogMessage(TEXT("Error: Can't start service\n"));
    return -1;
    }

    CloseServiceHandle(hService);
    CloseServiceHandle(hSCManager);
    return 0;
    }


    void getServicePath(TCHAR *path)
    {
    HKEY hKey = 0;
    TCHAR buf[260] = {0};
    DWORD dwBufSize = sizeof(buf);

    TCHAR subkey[260];
    wsprintf(subkey, L"SYSTEM\\CurrentControlSet\\services\\%s", svcName);

    if (RegOpenKey(HKEY_LOCAL_MACHINE, subkey, &hKey) == ERROR_SUCCESS)
    {
    int i = 0;
    if (RegQueryValueEx(hKey, TEXT("ImagePath"), NULL, NULL, (LPBYTE)buf, &dwBufSize) == ERROR_SUCCESS)
    {
    //wcsncpy(path, buf, dwBufSize);
    _wsplitpath(buf, NULL, path, NULL, NULL);
    }
    RegCloseKey(hKey);
    }
    }


    WCHAR* timeStamp(WCHAR* txt)
    {
    WCHAR* rc;
    WCHAR timestamp[16];
    time_t rawtime = time(0);
    tm *now = localtime(&rawtime);

    if (rawtime != -1)
    {
    wcsftime(timestamp, 16, __TEXT("%d_%m_%y.log"), gmtime(&curTime));
    rc = wcscat(txt, timestamp);
    }
    return(rc);
    }

    void addLogMessage(const TCHAR* t,...)
    {
    TCHAR format[MAX_PATH] = {0};
    TCHAR fname[MAX_PATH] = {0};
    getServicePath(format);
    timeStamp(fname);
    wcsncat(format, L"tw_", MAX_PATH);
    wcsncat(format, fname, MAX_PATH);

    TCHAR tmstp[MAX_PATH] = {0};
    timeStamp(tmstp);

    HANDLE h = ::CreateFile(format, GENERIC_WRITE, 0, 0, OPEN_ALWAYS, 0, 0);
    if (INVALID_HANDLE_VALUE != h)
    {
    unsigned long w = 0;
    va_list val;
    TCHAR f[0x1000];
    int l;

    va_start(val, t);
    wsprintf(f, L"%w - ", tmstp);
    l = _vsntprintf_s(f, sizeof(f)/sizeof(f[0]), _TRUNCATE, t, val);
    va_end(val);
    if (0 == SetFilePointer(h, 0, 0, FILE_END))
    {
    if (sizeof(short) == sizeof(TCHAR))
    {
    unsigned short unicode = 0xFeFF;
    WriteFile(h, (void*)&unicode, 2, &w, 0);
    }
    }
    WriteFile(h, (void*)f, l*sizeof(TCHAR), &w, 0);
    CloseHandle(h);
    }
    }
     
Загрузка...

Поделиться этой страницей