Простая программа HelloWorld обернутая сервисом.
От: arfaa  
Дата: 17.03.20 07:46
Оценка: -1
Добрый день, имеется рабочий windows service:
#include <iostream>
#include <Windows.h>
#include <conio.h>
#include <tchar.h>
#include <wchar.h>

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

#include <windows.h>
#include <tchar.h>
#include <strsafe.h>

#include <iostream>


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


//
// 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)
    {
        SvcInstall();
        return;
    }

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

    // 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()
{
    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"SimpleService329");

    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"SimpleService329");

    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)
    {
        std::ofstream file;
        file.open("codebind.txt", std::fstream::app);
        file << "Please writr this text to a file.\n this text is written using Stop\n";
        file.close();
        // 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;
    std::ofstream file;
    file.open("codebind.txt", std::fstream::app);
    file << "Please writr this text to a file.\n this text is written using Stop23\n";
    file.close();
    // 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);

        std::ofstream file;
        file.open("codebind.txt", std::fstream::app);
        file << "Please writr this text to a file.\n this text is written using Stop\n";
        file.close();

        return;
    }

    case SERVICE_CONTROL_INTERROGATE:
    {
        std::ofstream file;
        file.open("codebind.txt", std::fstream::app);
        file << "Please writr this text to a file.\n this text is written using Stop1\n";
        file.close();
        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"SimpleService329");

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

как сделать так, чтобы запускалось обычное консольное приложение:
int main()
{
cout << "Hello world";
std::ofstream file;
file.open("codebind.txt", std::fstream::app);
file << "Hello world\n";
file.close();
return 0;
}

но при этом работало бы как сервис?
Re: Простая программа HelloWorld обернутая сервисом.
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 17.03.20 08:46
Оценка:
Здравствуйте, arfaa, Вы писали:

A>как сделать так, чтобы запускалось обычное консольное приложение:

A>но при этом работало бы как сервис?

Никак, у них же точки входа разные: у сервиса это ServiceMain.
Re[2]: Простая программа HelloWorld обернутая сервисом.
От: arfaa  
Дата: 17.03.20 08:54
Оценка: -1
Здравствуйте, Nuzhny, Вы писали:

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


A>>как сделать так, чтобы запускалось обычное консольное приложение:

A>>но при этом работало бы как сервис?

N>Никак, у них же точки входа разные: у сервиса это ServiceMain.

Хорошо, а как в сервисе написать тогда какие-то действия, которые выполнялись бы?
Re[3]: Простая программа HelloWorld обернутая сервисом.
От: flаt  
Дата: 17.03.20 09:11
Оценка: -1
Здравствуйте, arfaa, Вы писали:

A>Хорошо, а как в сервисе написать тогда какие-то действия, которые выполнялись бы?


Прочитать книгу? Или хотя бы документацию по сервисам на MSDN.
Re[4]: Простая программа HelloWorld обернутая сервисом.
От: arfaa  
Дата: 17.03.20 09:21
Оценка: -3 :)
Здравствуйте, flаt, Вы писали:

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


A>>Хорошо, а как в сервисе написать тогда какие-то действия, которые выполнялись бы?


F>Прочитать книгу? Или хотя бы документацию по сервисам на MSDN.


Чтобы тебе по жизни отвечали на вопросы так же, на любые, вот приходишь ты в аптеку, говоришь:"Дайте мне что-нибудь от головы", тебе говорят:"А вы не могли бы изучить все лекарственные препараты по справочнику, а потом уже спрашивать", ты еще скажи свою книгу написать по сервисам.
Re[3]: Простая программа HelloWorld обернутая сервисом.
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 17.03.20 09:53
Оценка: 12 (2)
Здравствуйте, arfaa, Вы писали:

A>Хорошо, а как в сервисе написать тогда какие-то действия, которые выполнялись бы?


Всё таки совет про статьи не так плох, как кажется: раз
Автор(ы): Алексей Ширшов
Дата: 29.09.2002
В этой статье вашему вниманию предлагаются несколько классов, которые позволяют быстро и безболезненно создавать системные службы (также называемые сервисами) Windows 2000. Описанные в статье классы и методы работы со службами основаны на книге Дж. Рихтера и Дж. Кларка "Программирование серверных приложений для Windows 2000".
и два
Автор(ы): Сергей Холодилов
Дата: 22.06.2003
В статье описаны некоторые детали программирования служб Windows NT/2000/XP. Большая часть содержащихся в статье утверждений описывает реакцию Windows на какие-то действия службы. Если вы написали первую службу и хотите двигаться дальше, эта статья вам поможет.
.
Дело в том, что надо понимать, когда ты хочешь выполнить эти действия? Сервис — это не простая программа, которая запустилась-работает-закрылась. Сервис можно останавливать и ставить на паузу, у него есть свои события и возможность написания в системный лог. Рекомендую прочитать статьи выше, взять исходники в качестве "рыбы" для своего сервиса и вставлять свой пользовательский код именно туда, куда надо.
Re[5]: Простая программа HelloWorld обернутая сервисом.
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.03.20 10:11
Оценка: +1 -1
Здравствуйте, arfaa, Вы писали:

A>вот приходишь ты в аптеку, говоришь:"Дайте мне что-нибудь от головы"


Только полные дилетанты и лентяи спрашивают в аптеке "что-нибудь от головы". И фармацевтам, кстати, давно запрещено давать подобные рекомендации, их дело — продать то, что просит покупатель, и ничего больше. По-хорошему, фармацевтов-советчиков нужно гнать в три шеи.

A>тебе говорят:"А вы не могли бы изучить все лекарственные препараты по справочнику, а потом уже спрашивать"


Или обратиться к врачу. Да, заплатить таки придется.
Re[6]: Простая программа HelloWorld обернутая сервисом.
От: arfaa  
Дата: 17.03.20 10:18
Оценка: -1
Здравствуйте, Евгений Музыченко, Вы писали:

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


A>>вот приходишь ты в аптеку, говоришь:"Дайте мне что-нибудь от головы"


ЕМ>Только полные дилетанты и лентяи спрашивают в аптеке "что-нибудь от головы". И фармацевтам, кстати, давно запрещено давать подобные рекомендации, их дело — продать то, что просит покупатель, и ничего больше. По-хорошему, фармацевтов-советчиков нужно гнать в три шеи.


A>>тебе говорят:"А вы не могли бы изучить все лекарственные препараты по справочнику, а потом уже спрашивать"


ЕМ>Или обратиться к врачу. Да, заплатить таки придется.

Это у вас во Франции ?Там где я живу все происходит иначе или для лекарств тоже мсдн справочник прочитать надо?Много чего надо и много кого надо гнать, только реальность другая
Re[7]: Простая программа HelloWorld обернутая сервисом.
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 17.03.20 10:58
Оценка: +1 -1
Здравствуйте, arfaa, Вы писали:

ЕМ>>Или обратиться к врачу.

A>Это у вас во Франции ?Там где я живу все происходит иначе

Я не знаю, где Вы живете, а подбирать препараты по действию фармацевтам запрещено как раз в России. Они имеют право предложить различные формы выпуска в рамках назначения врача (или самоназначения покупателя, если препарат безрецептурный), но советовать препарат для лечения названного заболевания права не имеют.

A>или для лекарств тоже мсдн справочник прочитать надо?


Кто не ленив — читает справочник, медицинскую литературу и т.п. Кто ленив — идет к врачу. Ну, или сам себе, на свой страх и риск, назначает то, что помогло брату, свату, бабушке и прочим.

A>только реальность другая


Вы не только ленивы и заносчивы, но еще и дремучи. В частности, благодаря бесконтрольному приему антибактериальных средств мы сейчас имеем множество штаммов бактерий, резистентных практически ко всему, и люди от этого реально умирают. И часть умерших от коронавируса имеет к этому самое прямое отношение.
Re: Простая программа HelloWorld обернутая сервисом.
От: Мёртвый Даун Россия  
Дата: 18.03.20 10:06
Оценка:
Здравствуйте, arfaa, Вы писали:

A>как сделать так, чтобы запускалось обычное консольное приложение:


SC.EXE CREATE MyNewService binpath= c:\windows\system32\MyNewServHelloWorld.exe type= share start= auto depend= "+TDI Netbios"

https://support.microsoft.com/ru-ru/help/251192/how-to-create-a-windows-service-by-using-sc-exe
Только Путин, и никого кроме Путина! О Великий и Могучий Путин — царь на веки веков, навсегда!
Смотрю только Соловьева и Михеева, для меня это самые авторитетные эксперты.
КРЫМ НАШ! СКОРО И ВСЯ УКРАИНА БУДЕТ НАШЕЙ!
Re[3]: Простая программа HelloWorld обернутая сервисом.
От: Mr.Delphist  
Дата: 18.03.20 10:45
Оценка: :)
Здравствуйте, arfaa, Вы писали:

A>Хорошо, а как в сервисе написать тогда какие-то действия, которые выполнялись бы?


Опишите конкретные сценарии применения. Системный сервис — это не просто "абы какая программа", там есть определённые правила игры. Кто их не исполняет — того убивают.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.