Информация об изменениях

Сообщение Re[2]: Простой пример разработки Windows Service от 10.03.2020 15:30

Изменено 10.03.2020 16:19 arfaa

Re[2]: Простой пример разработки Windows Service
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, arfaa, Вы писали:


A>>
A>>    // Start a thread that will perform the main task of the service
A>>    HANDLE hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);

A>>    // Wait until our worker thread exits signaling that the service needs to stop
A>>    WaitForSingleObject(hThread, INFINITE);
A>>


Pzz>А зачем создавать отдельную нитку, и сразу же уходить в бесконечное ожидание ее завершения? Почему бы все то, что делает эта нитка, не делать в контексте основной нитки?


A>>Ошибка с goto

A>>Error C2362 initialization of 'hThread' is skipped by 'goto EXIT'

Pzz>goto не должен обходить инициализацию переменных. Иначе если исполнение пойдет по пути "goto", то в том месте, куда goto перейдет, переменная будет неинициализированная.



#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <tchar.h>
#include <wchar.h>

#include <fstream>
#include <string>
#include <vector>

using namespace std;

SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle;

#define serviceName TEXT("SimpleService")
LPCWSTR servicePath(L"C:\\Users\m.senin\\source\\repos\\ConsoleApplication1\\x64\\Debug\\ConsoleApplication1.exe");

int addLogMessage(const char* text)
{
    return printf(text);
}

void ControlHandler(DWORD request)
{
    switch (request)
    {
    case SERVICE_CONTROL_STOP:
        addLogMessage("Stopped.");

        serviceStatus.dwWin32ExitCode = 0;
        serviceStatus.dwCurrentState = SERVICE_STOPPED;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);
        return;

    case SERVICE_CONTROL_SHUTDOWN:
        addLogMessage("Shutdown.");

        serviceStatus.dwWin32ExitCode = 0;
        serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
        serviceStatus.dwWaitHint = 10000;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);
        return;

    default:
        break;
    }

    SetServiceStatus(serviceStatusHandle, &serviceStatus);

    return;
}

void ServiceMain(int, char**)
{
    int i = 0;

    serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    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;

    serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, (LPHANDLER_FUNCTION)ControlHandler);
    if (serviceStatusHandle == (SERVICE_STATUS_HANDLE)0) {
        return;
    }

    serviceStatus.dwCurrentState = SERVICE_RUNNING;
    SetServiceStatus(serviceStatusHandle, &serviceStatus);

    while (serviceStatus.dwCurrentState == SERVICE_RUNNING)
    {
        char buffer[255];
        sprintf_s(buffer, "%u", i);
        int result = addLogMessage(buffer);
        if (result) {
            serviceStatus.dwCurrentState = SERVICE_STOPPED;
            serviceStatus.dwWin32ExitCode = -1;
            SetServiceStatus(serviceStatusHandle, &serviceStatus);
            return;
        }
        i++;
    }

    return;
}

int InstallService() {
    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    if (!hSCManager) {
        addLogMessage("Error: Can't open Service Control Manager");
        return -1;
    }

    SC_HANDLE hService = CreateService(
        hSCManager,
        serviceName,
        serviceName,
        SERVICE_ALL_ACCESS,
        SERVICE_WIN32_OWN_PROCESS,
        SERVICE_DEMAND_START,
        SERVICE_ERROR_NORMAL,
        servicePath,
        NULL, NULL, NULL, NULL, NULL
    );

    if (!hService) {
        int err = GetLastError();
        switch (err) {
        case ERROR_ACCESS_DENIED:
            addLogMessage("Error: ERROR_ACCESS_DENIED");
            break;
        case ERROR_CIRCULAR_DEPENDENCY:
            addLogMessage("Error: ERROR_CIRCULAR_DEPENDENCY");
            break;
        case ERROR_DUPLICATE_SERVICE_NAME:
            addLogMessage("Error: ERROR_DUPLICATE_SERVICE_NAME");
            break;
        case ERROR_INVALID_HANDLE:
            addLogMessage("Error: ERROR_INVALID_HANDLE");
            break;
        case ERROR_INVALID_NAME:
            addLogMessage("Error: ERROR_INVALID_NAME");
            break;
        case ERROR_INVALID_PARAMETER:
            addLogMessage("Error: ERROR_INVALID_PARAMETER");
            break;
        case ERROR_INVALID_SERVICE_ACCOUNT:
            addLogMessage("Error: ERROR_INVALID_SERVICE_ACCOUNT");
            break;
        case ERROR_SERVICE_EXISTS:
            addLogMessage("Error: ERROR_SERVICE_EXISTS");
            break;
        default:
            addLogMessage("Error: Undefined");
        }
        CloseServiceHandle(hSCManager);
        return -1;
    }
    CloseServiceHandle(hService);

    CloseServiceHandle(hSCManager);
    addLogMessage("Success install service!");
    return 0;
}

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

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

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

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

int main(int argc, char* argv[])
{
    servicePath = (wchar_t*)argv[0];

    if (argc - 1 == 0)
    {
        wchar_t  ws[100];
        swprintf(ws, 100, L"SimpleService1");
        SERVICE_TABLE_ENTRY ServiceTable[2];
        ServiceTable[0].lpServiceName = ws;
        ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
        ServiceTable[1].lpServiceName = NULL;
        ServiceTable[1].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)NULL;

        if (!StartServiceCtrlDispatcher(ServiceTable))
        {
            addLogMessage("Error: StartServiceCtrlDispatcher");
        }
    }
    else if (strcmp(argv[argc - 1], "install") == 0)
    {
        InstallService();
    }
    else if (strcmp(argv[argc - 1], "remove") == 0)
    {
        RemoveService();
    }
    else if (strcmp(argv[argc - 1], "start") == 0)
    {
        StartService();
    }

    return 0;//a.exec();
}


Рабочий код, Инсталляция и Удаление сервиса работает, а вот Запуск не получается.... в чем косяк?
p.s. Студия запущена от имени админа.
Re[2]: Простой пример разработки Windows Service
Здравствуйте, Pzz, Вы писали:

Pzz>Здравствуйте, arfaa, Вы писали:


A>>
A>>    // Start a thread that will perform the main task of the service
A>>    HANDLE hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);

A>>    // Wait until our worker thread exits signaling that the service needs to stop
A>>    WaitForSingleObject(hThread, INFINITE);
A>>


Pzz>А зачем создавать отдельную нитку, и сразу же уходить в бесконечное ожидание ее завершения? Почему бы все то, что делает эта нитка, не делать в контексте основной нитки?


A>>Ошибка с goto

A>>Error C2362 initialization of 'hThread' is skipped by 'goto EXIT'

Pzz>goto не должен обходить инициализацию переменных. Иначе если исполнение пойдет по пути "goto", то в том месте, куда goto перейдет, переменная будет неинициализированная.



#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <tchar.h>
#include <wchar.h>

#include <fstream>
#include <string>
#include <vector>

using namespace std;

SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE serviceStatusHandle;

#define serviceName TEXT("SimpleService")
LPCWSTR servicePath(L"C:\\Users\m.sexios\\source\\repos\\ConsoleApplication1\\x64\\Debug\\ConsoleApplication1.exe");

int addLogMessage(const char* text)
{
    return printf(text);
}

void ControlHandler(DWORD request)
{
    switch (request)
    {
    case SERVICE_CONTROL_STOP:
        addLogMessage("Stopped.");

        serviceStatus.dwWin32ExitCode = 0;
        serviceStatus.dwCurrentState = SERVICE_STOPPED;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);
        return;

    case SERVICE_CONTROL_SHUTDOWN:
        addLogMessage("Shutdown.");

        serviceStatus.dwWin32ExitCode = 0;
        serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
        serviceStatus.dwWaitHint = 10000;
        SetServiceStatus(serviceStatusHandle, &serviceStatus);
        return;

    default:
        break;
    }

    SetServiceStatus(serviceStatusHandle, &serviceStatus);

    return;
}

void ServiceMain(int, char**)
{
    int i = 0;

    serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    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;

    serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, (LPHANDLER_FUNCTION)ControlHandler);
    if (serviceStatusHandle == (SERVICE_STATUS_HANDLE)0) {
        return;
    }

    serviceStatus.dwCurrentState = SERVICE_RUNNING;
    SetServiceStatus(serviceStatusHandle, &serviceStatus);

    while (serviceStatus.dwCurrentState == SERVICE_RUNNING)
    {
        char buffer[255];
        sprintf_s(buffer, "%u", i);
        int result = addLogMessage(buffer);
        if (result) {
            serviceStatus.dwCurrentState = SERVICE_STOPPED;
            serviceStatus.dwWin32ExitCode = -1;
            SetServiceStatus(serviceStatusHandle, &serviceStatus);
            return;
        }
        i++;
    }

    return;
}

int InstallService() {
    SC_HANDLE hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
    if (!hSCManager) {
        addLogMessage("Error: Can't open Service Control Manager");
        return -1;
    }

    SC_HANDLE hService = CreateService(
        hSCManager,
        serviceName,
        serviceName,
        SERVICE_ALL_ACCESS,
        SERVICE_WIN32_OWN_PROCESS,
        SERVICE_DEMAND_START,
        SERVICE_ERROR_NORMAL,
        servicePath,
        NULL, NULL, NULL, NULL, NULL
    );

    if (!hService) {
        int err = GetLastError();
        switch (err) {
        case ERROR_ACCESS_DENIED:
            addLogMessage("Error: ERROR_ACCESS_DENIED");
            break;
        case ERROR_CIRCULAR_DEPENDENCY:
            addLogMessage("Error: ERROR_CIRCULAR_DEPENDENCY");
            break;
        case ERROR_DUPLICATE_SERVICE_NAME:
            addLogMessage("Error: ERROR_DUPLICATE_SERVICE_NAME");
            break;
        case ERROR_INVALID_HANDLE:
            addLogMessage("Error: ERROR_INVALID_HANDLE");
            break;
        case ERROR_INVALID_NAME:
            addLogMessage("Error: ERROR_INVALID_NAME");
            break;
        case ERROR_INVALID_PARAMETER:
            addLogMessage("Error: ERROR_INVALID_PARAMETER");
            break;
        case ERROR_INVALID_SERVICE_ACCOUNT:
            addLogMessage("Error: ERROR_INVALID_SERVICE_ACCOUNT");
            break;
        case ERROR_SERVICE_EXISTS:
            addLogMessage("Error: ERROR_SERVICE_EXISTS");
            break;
        default:
            addLogMessage("Error: Undefined");
        }
        CloseServiceHandle(hSCManager);
        return -1;
    }
    CloseServiceHandle(hService);

    CloseServiceHandle(hSCManager);
    addLogMessage("Success install service!");
    return 0;
}

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

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

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

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

int main(int argc, char* argv[])
{
    servicePath = (wchar_t*)argv[0];

    if (argc - 1 == 0)
    {
        wchar_t  ws[100];
        swprintf(ws, 100, L"SimpleService1");
        SERVICE_TABLE_ENTRY ServiceTable[2];
        ServiceTable[0].lpServiceName = ws;
        ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
        ServiceTable[1].lpServiceName = NULL;
        ServiceTable[1].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)NULL;

        if (!StartServiceCtrlDispatcher(ServiceTable))
        {
            addLogMessage("Error: StartServiceCtrlDispatcher");
        }
    }
    else if (strcmp(argv[argc - 1], "install") == 0)
    {
        InstallService();
    }
    else if (strcmp(argv[argc - 1], "remove") == 0)
    {
        RemoveService();
    }
    else if (strcmp(argv[argc - 1], "start") == 0)
    {
        StartService();
    }

    return 0;//a.exec();
}


Рабочий код, Инсталляция и Удаление сервиса работает, а вот Запуск не получается.... в чем косяк?
p.s. Студия запущена от имени админа.