Простой пример разработки Windows Service
От: arfaa  
Дата: 06.03.20 14:52
Оценка:
Добрый день , коллеги, хочется найти простой пример создания виндусовского сервиса. Интернет облазил, нашел один пример, но после некоторых манипуляций и исправления ошибок одна остается и как с ней бороться не пойму, киньте рабочий код простого сервиса или поправьте меня, где я не прав в коде:
#include <Windows.h>
#include <tchar.h>
#include <string>
#include <cstdio>


#define SERVICE_NAME  _T("My Sample Service")


SERVICE_STATUS        g_ServiceStatus = { 0 };
SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
HANDLE                g_ServiceStopEvent = INVALID_HANDLE_VALUE;

VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
VOID WINAPI ServiceCtrlHandler(DWORD);
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam);


VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
{
    DWORD Status = E_FAIL;

    // Register our service control handler with the SCM
    g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);

    if (g_StatusHandle == NULL)
    {
        goto EXIT;
    }

    // Tell the service controller we are starting
    ZeroMemory(&g_ServiceStatus, sizeof(g_ServiceStatus));
    g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    g_ServiceStatus.dwControlsAccepted = 0;
    g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwServiceSpecificExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 0;

    if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
    {
        OutputDebugString(_T(
            "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    }

    /*
     * Perform tasks necessary to start the service here
     */

     // Create a service stop event to wait on later
    g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (g_ServiceStopEvent == NULL)
    {
        // Error creating event
        // Tell service controller we are stopped and exit
        g_ServiceStatus.dwControlsAccepted = 0;
        g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
        g_ServiceStatus.dwWin32ExitCode = GetLastError();
        g_ServiceStatus.dwCheckPoint = 1;

        if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
        {
            OutputDebugString(_T(
                "My Sample Service: ServiceMain: SetServiceStatus returned error"));
        }
        goto EXIT;
    }

    // Tell the service controller we are started
    g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 0;

    if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
    {
        OutputDebugString(_T(
            "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    }

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

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


    /*
     * Perform any cleanup tasks
     */

    CloseHandle(g_ServiceStopEvent);

    // Tell the service controller we are stopped
    g_ServiceStatus.dwControlsAccepted = 0;
    g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
    g_ServiceStatus.dwWin32ExitCode = 0;
    g_ServiceStatus.dwCheckPoint = 3;

    if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE)
    {
        OutputDebugString(_T(
            "My Sample Service: ServiceMain: SetServiceStatus returned error"));
    }

EXIT:
    return;
}

int _tmain(int argc, TCHAR* argv[])
{
    SERVICE_TABLE_ENTRY ServiceTable[] =
    {
        {(LPWSTR)SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
        {NULL, NULL}
    };

    if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)
    {
        return GetLastError();
    }

    return 0;
}


Ошибка с goto
Error C2362 initialization of 'hThread' is skipped by 'goto EXIT'
Re: Простой пример разработки Windows Service
От: CaptainFlint Россия http://flint-inc.ru/
Дата: 06.03.20 15:04
Оценка:
Здравствуйте, arfaa, Вы писали:

A>Ошибка с goto

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

Вынеси объявление hThread за пределы goto:

HANDLE hThread = NULL;
...
goto EXIT;
...
hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);
Почему же, ё-моё, ты нигде не пишешь «ё»?
Re[2]: Простой пример разработки Windows Service
От: arfaa  
Дата: 06.03.20 15:09
Оценка:
Здравствуйте, CaptainFlint, Вы писали:

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


A>>Ошибка с goto

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

CF>Вынеси объявление hThread за пределы goto:


CF>
CF>HANDLE hThread = NULL;
CF>...
CF>goto EXIT;
CF>...
CF>hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);
CF>

А можно поподробнее, через контрл Ц + контрл В с моим кодом показать, где я неправильно пишу?
Re[3]: Простой пример разработки Windows Service
От: arfaa  
Дата: 06.03.20 15:14
Оценка:
Здравствуйте, arfaa, Вы писали:

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


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


A>>>Ошибка с goto

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

CF>>Вынеси объявление hThread за пределы goto:


CF>>
CF>>HANDLE hThread = NULL;
CF>>...
CF>>goto EXIT;
CF>>...
CF>>hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);
CF>>

A>А можно поподробнее, через контрл Ц + контрл В с моим кодом показать, где я неправильно пишу?

Поправил, что написано выше, теперь следущие ошибки:



Error LNK2019 unresolved external symbol "void __cdecl ServiceCtrlHandler(unsigned long)" (?ServiceCtrlHandler@@YAXK@Z) referenced in function "void __cdecl ServiceMain(unsigned long,wchar_t * *)" (?ServiceMain@@YAXKPEAPEA_W@Z) ConsoleApplication3


Error LNK2019 unresolved external symbol "unsigned long __cdecl ServiceWorkerThread(void *)" (?ServiceWorkerThread@@YAKPEAX@Z) referenced in function "void __cdecl ServiceMain(unsigned long,wchar_t * *)" (?ServiceMain@@YAXKPEAPEA_W@Z)
Отредактировано 06.03.2020 15:17 arfaa . Предыдущая версия .
Re[4]: Простой пример разработки Windows Service
От: CaptainFlint Россия http://flint-inc.ru/
Дата: 06.03.20 16:00
Оценка:
Здравствуйте, arfaa, Вы писали:

A>Error LNK2019 unresolved external symbol "void __cdecl ServiceCtrlHandler(unsigned long)" (?ServiceCtrlHandler@@YAXK@Z) referenced in function "void __cdecl ServiceMain(unsigned long,wchar_t * *)" (?ServiceMain@@YAXKPEAPEA_W@Z) ConsoleApplication3


A>Error LNK2019 unresolved external symbol "unsigned long __cdecl ServiceWorkerThread(void *)" (?ServiceWorkerThread@@YAKPEAX@Z) referenced in function "void __cdecl ServiceMain(unsigned long,wchar_t * *)" (?ServiceMain@@YAXKPEAPEA_W@Z)


Мне кажется, стоит сначала разобраться в основах программирования на языке C/C++, и лишь потом браться за написание сервисов.
Эти две функции объявлены, используются в коде, но тела самих этих функций нигде не определены. Либо не хватает кода в примере, либо не подключен дополнительный файл с исходником.
Почему же, ё-моё, ты нигде не пишешь «ё»?
Отредактировано 06.03.2020 16:57 CaptainFlint . Предыдущая версия .
Re: Простой пример разработки Windows Service
От: Слава  
Дата: 06.03.20 16:49
Оценка: 1 (1) -1
Здравствуйте, arfaa, Вы писали:

A>Добрый день , коллеги, хочется найти простой пример создания виндусовского сервиса. Интернет облазил, нашел один пример, но после некоторых манипуляций и исправления ошибок одна остается и как с ней бороться не пойму, киньте рабочий код простого сервиса или поправьте меня, где я не прав в коде:


Когда-то в начале нулевых я писал виндовые сервисы на Delphi. Вам то же самое рекомендую сделать, взяв скажем Lazarus. Оно будет проще и вам не придётся разбираться одновременно с адскими С++ и с winapi.

И я бы добавил в ваш код две новые функции — регистрация собственно сервиса и удаление регистрации. Чтобы он был самодостаточным.
Re: Простой пример разработки Windows Service
От: Alexander_S_U https://github.com/alexanders-code/cmdxmlinstaller
Дата: 06.03.20 18:07
Оценка:
Здравствуйте, arfaa, Вы писали:

A>Добрый день , коллеги, хочется найти простой пример создания виндусовского сервиса. Интернет облазил, нашел один пример, но после некоторых манипуляций и исправления ошибок одна остается и как с ней бороться не пойму, киньте рабочий код простого сервиса или поправьте меня, где я не прав в коде:


Посмотрите во эту статью Пишем сервис. Что может быть проще!
Автор(ы): Алексей Ширшов
Дата: 29.09.2002
В этой статье вашему вниманию предлагаются несколько классов, которые позволяют быстро и безболезненно создавать системные службы (также называемые сервисами) Windows 2000. Описанные в статье классы и методы работы со службами основаны на книге Дж. Рихтера и Дж. Кларка "Программирование серверных приложений для Windows 2000".
я когда то по ней разбирался
https://github.com/alexanders-code/cmdxmlinstaller
Re[2]: Простой пример разработки Windows Service
От: arfaa  
Дата: 08.03.20 18:33
Оценка:
Здравствуйте, Alexander_S_U, Вы писали:

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


A>>Добрый день , коллеги, хочется найти простой пример создания виндусовского сервиса. Интернет облазил, нашел один пример, но после некоторых манипуляций и исправления ошибок одна остается и как с ней бороться не пойму, киньте рабочий код простого сервиса или поправьте меня, где я не прав в коде:


A_S>Посмотрите во эту статью Пишем сервис. Что может быть проще!
Автор(ы): Алексей Ширшов
Дата: 29.09.2002
В этой статье вашему вниманию предлагаются несколько классов, которые позволяют быстро и безболезненно создавать системные службы (также называемые сервисами) Windows 2000. Описанные в статье классы и методы работы со службами основаны на книге Дж. Рихтера и Дж. Кларка "Программирование серверных приложений для Windows 2000".
я когда то по ней разбирался

Спасибо, почитаю!!!
Re[2]: Простой пример разработки Windows Service
От: arfaa  
Дата: 08.03.20 18:36
Оценка:
Здравствуйте, Слава, Вы писали:

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


A>>Добрый день , коллеги, хочется найти простой пример создания виндусовского сервиса. Интернет облазил, нашел один пример, но после некоторых манипуляций и исправления ошибок одна остается и как с ней бороться не пойму, киньте рабочий код простого сервиса или поправьте меня, где я не прав в коде:


С>Когда-то в начале нулевых я писал виндовые сервисы на Delphi. Вам то же самое рекомендую сделать, взяв скажем Lazarus. Оно будет проще и вам не придётся разбираться одновременно с адскими С++ и с winapi.


С>И я бы добавил в ваш код две новые функции — регистрация собственно сервиса и удаление регистрации. Чтобы он был самодостаточным.

Спасибо, что не оставили тоже без ответа!
Re: Простой пример разработки Windows Service
От: EreTIk EreTIk's Box
Дата: 10.03.20 09:20
Оценка:
Здравствуйте, arfaa, Вы писали:

A>Добрый день , коллеги, хочется найти простой пример создания виндусовского сервиса. Интернет облазил, нашел один пример, но ...


Я бы порекомендовал все же официальную документацию:
Re: Простой пример разработки Windows Service
От: Pzz Россия https://github.com/alexpevzner
Дата: 10.03.20 09:23
Оценка:
Здравствуйте, 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>


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

A>Ошибка с goto

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

goto не должен обходить инициализацию переменных. Иначе если исполнение пойдет по пути "goto", то в том месте, куда goto перейдет, переменная будет неинициализированная.
Re[2]: Простой пример разработки Windows Service
От: arfaa  
Дата: 10.03.20 15:30
Оценка:
Здравствуйте, 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. Студия запущена от имени админа.
Отредактировано 10.03.2020 16:19 arfaa . Предыдущая версия .
Re[3]: Простой пример разработки Windows Service
От: morgot  
Дата: 11.03.20 10:08
Оценка:
Здравствуйте, arfaa, Вы писали:

1. попробуйте тут получить LastError ( addLogMessage("Error: Can't start service"); )
2. попробуйте запустить ваш сервис сторонним приложением, тем же SCM от Рихтера или банально через консоль (sc start ), что будет писать.
Может, проблема в нем самом.
Re[4]: Простой пример разработки Windows Service
От: arfaa  
Дата: 11.03.20 13:32
Оценка:
Здравствуйте, morgot, Вы писали:

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


M>1. попробуйте тут получить LastError ( addLogMessage("Error: Can't start service"); )

M>2. попробуйте запустить ваш сервис сторонним приложением, тем же SCM от Рихтера или банально через консоль (sc start ), что будет писать.
M>Может, проблема в нем самом.
Реализовал сервис, который корректно работает, вот код:
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>

#include <iostream>
#include <fstream>


#pragma comment(lib, "advapi32.lib")

//#define SVCNAME TEXT("SvcName")

SERVICE_STATUS          gSvcStatus;
SERVICE_STATUS_HANDLE   gSvcStatusHandle;
HANDLE                  ghSvcStopEvent = NULL;

VOID SvcInstall(void);
VOID WINAPI SvcCtrlHandler(DWORD);
VOID WINAPI SvcMain(DWORD, LPTSTR*);

VOID ReportSvcStatus(DWORD, DWORD, DWORD);
VOID SvcInit(DWORD, LPTSTR*);
VOID SvcReportEvent(LPTSTR);

using namespace std;

//
// Purpose: 
//   Entry point for the process
//
// Parameters:
//   None
// 
// Return value:
//   None
//
void __cdecl _tmain(int argc, TCHAR* argv[])
{
    // If command-line parameter is "install", install the service. 
    // Otherwise, the service is probably being started by the SCM.

    if (lstrcmpi(argv[1], TEXT("install")) == 0)
    {
        //ofstream file;
       // file.open("codebind.txt", std::fstream::app);
       // file << "Please writr this text to a file.\n this text is written using C---\n";
       // file.close();
        SvcInstall();
        return;
    }

    wchar_t  SVCNAME[100];
    swprintf(SVCNAME, 100, L"SimpleService3");

    // TO_DO: Add any additional services for the process to this table.
    SERVICE_TABLE_ENTRY DispatchTable[] =
    {
        { SVCNAME, (LPSERVICE_MAIN_FUNCTION)SvcMain },
        { NULL, NULL }
    };

    // This call returns when the service has stopped. 
    // The process should simply terminate when the call returns.

    if (!StartServiceCtrlDispatcher(DispatchTable))
    {
        //SvcReportEvent(TEXT("StartServiceCtrlDispatcher"));
    }
}

//
// Purpose: 
//   Installs a service in the SCM database
//
// Parameters:
//   None
// 
// Return value:
//   None
//
VOID SvcInstall()
{
    string str = "erere";
    SC_HANDLE schSCManager;
    SC_HANDLE schService;
    TCHAR szPath[MAX_PATH];

    if (!GetModuleFileName(NULL, szPath, MAX_PATH))
    {
        printf("Cannot install service (%d)\n", GetLastError());
        return;
    }

    // Get a handle to the SCM database. 

    schSCManager = OpenSCManager(
        NULL,                    // local computer
        NULL,                    // ServicesActive database 
        SC_MANAGER_ALL_ACCESS);  // full access rights 

    if (NULL == schSCManager)
    {
        printf("OpenSCManager failed (%d)\n", GetLastError());
        return;
    }

    // Create the service
    wchar_t  SVCNAME[100];
    swprintf(SVCNAME, 100, L"SimpleService3");
    schService = CreateService(
        schSCManager,              // SCM database 
        SVCNAME,                   // name of service 
        SVCNAME,                   // service name to display 
        SERVICE_ALL_ACCESS,        // desired access 
        SERVICE_WIN32_OWN_PROCESS, // service type 
        SERVICE_DEMAND_START,      // start type 
        SERVICE_ERROR_NORMAL,      // error control type 
        szPath,                    // path to service's binary 
        NULL,                      // no load ordering group 
        NULL,                      // no tag identifier 
        NULL,                      // no dependencies 
        NULL,                      // LocalSystem account 
        NULL);                     // no password 

    if (schService == NULL)
    {
        printf("CreateService failed (%d)\n", GetLastError());
        CloseServiceHandle(schSCManager);
        return;
    }
    else printf("Service installed successfully\n");

    CloseServiceHandle(schService);
    CloseServiceHandle(schSCManager);
}

//
// Purpose: 
//   Entry point for the service
//
// Parameters:
//   dwArgc - Number of arguments in the lpszArgv array
//   lpszArgv - Array of strings. The first string is the name of
//     the service and subsequent strings are passed by the process
//     that called the StartService function to start the service.
// 
// Return value:
//   None.
//
VOID WINAPI SvcMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
    // Register the handler function for the service

    wchar_t  SVCNAME[100];
    swprintf(SVCNAME, 100, L"SimpleService3");
    gSvcStatusHandle = RegisterServiceCtrlHandler(
        SVCNAME,
        SvcCtrlHandler);

    if (!gSvcStatusHandle)
    {
        //SvcReportEvent(TEXT("RegisterServiceCtrlHandler"));
        return;
    }

    // These SERVICE_STATUS members remain as set here

    gSvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    gSvcStatus.dwServiceSpecificExitCode = 0;

    // Report initial status to the SCM

    ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000);

    // Perform service-specific initialization and work.

    SvcInit(dwArgc, lpszArgv);
}

//
// Purpose: 
//   The service code
//
// Parameters:
//   dwArgc - Number of arguments in the lpszArgv array
//   lpszArgv - Array of strings. The first string is the name of
//     the service and subsequent strings are passed by the process
//     that called the StartService function to start the service.
// 
// Return value:
//   None
//
VOID SvcInit(DWORD dwArgc, LPTSTR* lpszArgv)
{
    // TO_DO: Declare and set any required variables.
    //   Be sure to periodically call ReportSvcStatus() with 
    //   SERVICE_START_PENDING. If initialization fails, call
    //   ReportSvcStatus with SERVICE_STOPPED.

    // Create an event. The control handler function, SvcCtrlHandler,
    // signals this event when it receives the stop control code.

    ghSvcStopEvent = CreateEvent(
        NULL,    // default security attributes
        TRUE,    // manual reset event
        FALSE,   // not signaled
        NULL);   // no name

    if (ghSvcStopEvent == NULL)
    {
        ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
        return;
    }

    // Report running status when initialization is complete.

    ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0);

    // TO_DO: Perform work until service stops.

    while (1)
    {
        // Check whether to stop the service.

        WaitForSingleObject(ghSvcStopEvent, INFINITE);

        ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0);
        return;
    }
}

//
// Purpose: 
//   Sets the current service status and reports it to the SCM.
//
// Parameters:
//   dwCurrentState - The current state (see SERVICE_STATUS)
//   dwWin32ExitCode - The system error code
//   dwWaitHint - Estimated time for pending operation, 
//     in milliseconds
// 
// Return value:
//   None
//
VOID ReportSvcStatus(DWORD dwCurrentState,
    DWORD dwWin32ExitCode,
    DWORD dwWaitHint)
{
    static DWORD dwCheckPoint = 1;

    // Fill in the SERVICE_STATUS structure.

    gSvcStatus.dwCurrentState = dwCurrentState;
    gSvcStatus.dwWin32ExitCode = dwWin32ExitCode;
    gSvcStatus.dwWaitHint = dwWaitHint;

    if (dwCurrentState == SERVICE_START_PENDING)
        gSvcStatus.dwControlsAccepted = 0;
    else gSvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;

    if ((dwCurrentState == SERVICE_RUNNING) ||
        (dwCurrentState == SERVICE_STOPPED))
        gSvcStatus.dwCheckPoint = 0;
    else gSvcStatus.dwCheckPoint = dwCheckPoint++;

    // Report the status of the service to the SCM.
    SetServiceStatus(gSvcStatusHandle, &gSvcStatus);
}

//
// Purpose: 
//   Called by SCM whenever a control code is sent to the service
//   using the ControlService function.
//
// Parameters:
//   dwCtrl - control code
// 
// Return value:
//   None
//
VOID WINAPI SvcCtrlHandler(DWORD dwCtrl)
{
    // Handle the requested control code. 

    switch (dwCtrl)
    {
    case SERVICE_CONTROL_STOP:
        ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0);

        // Signal the service to stop.

        SetEvent(ghSvcStopEvent);
        ReportSvcStatus(gSvcStatus.dwCurrentState, NO_ERROR, 0);

        return;

    case SERVICE_CONTROL_INTERROGATE:
        break;

    default:
        break;
    }

}

//
// Purpose: 
//   Logs messages to the event log
//
// Parameters:
//   szFunction - name of function that failed
// 
// Return value:
//   None
//
// Remarks:
//   The service must have an entry in the Application event log.
//
VOID SvcReportEvent(LPTSTR szFunction)
{
    HANDLE hEventSource;
    LPCTSTR lpszStrings[2];
    TCHAR Buffer[80];

    wchar_t  SVCNAME[100];
    swprintf(SVCNAME, 100, L"SimpleService3");

    hEventSource = RegisterEventSource(NULL, SVCNAME);

    if (NULL != hEventSource)
    {
        StringCchPrintf(Buffer, 80, TEXT("%s failed with %d"), szFunction, GetLastError());

        lpszStrings[0] = SVCNAME;
        lpszStrings[1] = Buffer;

        ReportEvent(hEventSource,        // event log handle
            EVENTLOG_ERROR_TYPE, // event type
            0,                   // event category
            0,//SVC_ERROR,           // event identifier
            NULL,                // no security identifier
            2,                   // size of lpszStrings array
            0,                   // no binary data
            lpszStrings,         // array of strings
            NULL);               // no binary data

        DeregisterEventSource(hEventSource);
    }
}

но как только в main я вставляю любой код:
std::string str = "123";

то программа перестает собираться:


Что за фигня?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.