Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Служба Windows XP, Служба Windows XP 
:(
    Опции темы
alt_7
Дата 19.3.2008, 09:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 12.5.2007

Репутация: нет
Всего: нет



Доброе время суток!
Подскажите, как создать, запустить программу как службу Windows XP. Если у кого есть пример киньте.
PM MAIL   Вверх
Alca
Дата 19.3.2008, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 5
Всего: 50



Код

#include <windows.h>
#include <iostream.h>

int main()
{
  SC_HANDLE  hServiceControlManager, hService;

  // связываемся с менеджером сервисов
  hServiceControlManager = OpenSCManager(
    NULL,      // локальная машина
    NULL,      // активная база данных сервисов
    SC_MANAGER_CREATE_SERVICE  // возможно создание сервиса
    );
  if (hServiceControlManager == NULL)
  {
    cout << "Open service control manager failed." << endl
      << "The last error code: " << GetLastError() << endl
      << "Press any key to exit." << endl;
    cin.get(); 

    return 0;
  }
  cout << "Service control manager is opened." << endl
    << "Press any key to continue." << endl;
  cin.get();

  // устанавливаем новый сервис
  hService = CreateService(
    hServiceControlManager,  // дескриптор менеджера сервисов
    "DemoService",           // внутреннее имя сервиса, используемое SCM
    "Demo_Service",          // внешнее имя сервиса в панели управления
    SERVICE_ALL_ACCESS,      // полный контроль над сервисом
    SERVICE_WIN32_OWN_PROCESS,   // сервис является процессом
    SERVICE_DEMAND_START,    // запускается сервис по требованию
    SERVICE_ERROR_NORMAL,    // обработка ошибок нормальная
    "C:\\DemoService.exe",   // путь к сервису
    NULL,                    // сервис не принадлежит к группе
    NULL,        // тэг группы не изменяется
    NULL,        // сервис не зависит от других сервисов
    NULL,        // имя совпадает с текущим именем учетной записи
    NULL         // пароля нет
  );
  if (hService == NULL)
  {
    cout << "Create service failed." << endl
      << "The last error code: " << GetLastError() << endl
      << "Press any key to exit." << endl;
    cin.get(); 

    // закрываем дескриптор менеджера сервисов
    CloseServiceHandle(hServiceControlManager);

    return 0;
  }

  cout << "Service is installed." << endl
    << "Press any key to exit." << endl;
  cin.get();

  // закрываем дескрипторы
  CloseServiceHandle(hService);
  CloseServiceHandle(hServiceControlManager);

  return 0;
}



--------------------
PM WWW ICQ Skype Jabber   Вверх
alt_7
Дата 19.3.2008, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 12.5.2007

Репутация: нет
Всего: нет



Спасибо за ответ и за пример. Есть вопрос еще. После того как скомпилировал пример и пытаюсь запустить службу. Выдается окно с тексом: Ошибка 1053: Служба не ответила запрос своевременно.
Подскажите как это исправить?
PM MAIL   Вверх
586
Дата 19.3.2008, 11:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2243
Регистрация: 8.5.2006

Репутация: 39
Всего: 146



Такое обычно бывает, когда обычное приложение как службу запускают.
PM   Вверх
alt_7
Дата 19.3.2008, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 12.5.2007

Репутация: нет
Всего: нет



Цитата(586 @ 19.3.2008,  11:56)
Такое обычно бывает, когда обычное приложение как службу запускают.

Хорошо а как надо? Я пробывал для создания приложения в C++ Builder использывать File->New->Service Application. Но у меня выдается тоже самое сообщение.
PM MAIL   Вверх
alt_7
Дата 21.3.2008, 12:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 12.5.2007

Репутация: нет
Всего: нет



Так ктонить знает как с этим бороться?
PM MAIL   Вверх
Pulse69
Дата 21.3.2008, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 28.4.2006
Где: Хабаровск

Репутация: 8
Всего: 10



alt_7,  в обработчике запуска службы нужно перевести её в состояние SERVICE_START_PENDING, потом в SERVICE_RUNNING. Без этого контроллер сервисов посчитает, что служба зависла при попытке старта, выдаст вот такое окошечко и всё.
Как всё это сделать в Builder - пожалуйста, в их раздел.
А вообще, по написанию сервисов здесь очень много тем есть. Попробуйте поискать примеры.


Это сообщение отредактировал(а) Pulse69 - 21.3.2008, 12:29
--------------------
Ctrl+Alt+Reset 
PM MAIL   Вверх
asd
Дата 21.3.2008, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 89
Регистрация: 25.6.2006

Репутация: 1
Всего: 1



Никогда не писал сервисов, так что к нижеописанному относится следует с недовериемsmile))

Попробуйте вызвать ф-ию StartServiceCtrlDispatcher при запуске. Ещё "Внутреннее устройство Windows" Соломона, Русиновича можно вочитать, на предмет того, как сервисы запускаются
PM MAIL   Вверх
EnergoHokum
Дата 25.3.2008, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: 3
Всего: 6



Лови исходники:

Это -- регистрация сервиса в системе

Код

#include <stdio.h>
#include <string.h>
#include <windows.h>
//-------------------------------------------------------------------------
/* g++ -Wall -o ./install.exe ./install.cpp */
//-------------------------------------------------------------------------
char infomes[0x200];
char servicedir[MAX_PATH];
//-------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,    \
                 LPSTR lpCmdLine,int nCmdShow            \
                 )
{
    strcpy(infomes,"Service succesfull creat at path:\n");
    //strcpy(servicedir,"%SystemRoot%\\System32\\service.exe");
    strcpy(servicedir,"E:\\Hokum\\Program\\CPP\\testService_4\\service.exe");

    SC_HANDLE scm=::OpenSCManager(NULL,NULL,SC_MANAGER_CREATE_SERVICE);
    if(scm)
    {
        SC_HANDLE svc=::CreateService(scm,"Test service","Test service",    \
                                0,                                \
                                SERVICE_WIN32_OWN_PROCESS |        \
                                SERVICE_INTERACTIVE_PROCESS,        \
                                SERVICE_AUTO_START,                \
                                SERVICE_ERROR_IGNORE,                \
                                servicedir,NULL,NULL,                    \
                                NULL,NULL,NULL                        \
                                                                    );
        if(svc)
        {
            ::CloseServiceHandle(svc);
            strcat(infomes,servicedir);
            ::MessageBox(NULL,infomes,"Install",MB_OK);
        }
        ::CloseServiceHandle(scm);
    }
    else
    {
        ::MessageBox(NULL,"Error: Can`not create service","Install",MB_OK);
    }
    return 0;
}


Это, соответственно, снятие регистрации

Код

#include <windows.h>
//-------------------------------------------------------------------------
/* g++ -Wall -o ./uninstall.exe ./uninstall.cpp */
//-------------------------------------------------------------------------
INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,    \
                 LPSTR lpCmdLine,int nCmdShow            \
                 )
{
    SC_HANDLE scm=::OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    if(scm)
    {
        SC_HANDLE svc=::OpenService(scm,"Test service",                    \
                                STANDARD_RIGHTS_REQUIRED        \
                                );
        ::DeleteService(svc);
        if(svc)
        {
            ::CloseServiceHandle(svc);
            ::MessageBox(NULL,"Succefull","Uninstall",MB_OK);
        }
        ::CloseServiceHandle(scm);
    }
    else
    {
        ::MessageBox(NULL,"Error: Can`not uninstall service","Uninstall",MB_OK);
    }
    return 0;
}


Это -- исходник службы, я его сильно прокомментировал

Код

#include <stdio.h>
#include <string.h>
#include <windows.h>
#include "service.h"
//-------------------------------------------------------------------------
/* Упреждающее объявление WinMain */
extern "C" INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,    \
                        LPSTR lpCmdLine,int nCmdShow            \
                        );
//-------------------------------------------------------------------------
/* Управляющее событие */
HANDLE hControlEvent;
/**/
HMODULE g_module=NULL;
/* Текущий статус сервиса */
SERVICE_STATUS ss;
/* Handle для структуры статуса */
SERVICE_STATUS_HANDLE ssh;
/* Объединяем в одну структуру для возможности передачи указателя на неё */
struct SsSsh { SERVICE_STATUS ss; SERVICE_STATUS_HANDLE ssh; };
//-------------------------------------------------------------------------
VOID SetSomeServiceStatus(DWORD dwCurrentState,        \
                    DWORD dwWin32ExitCode,    \
                    DWORD dwWaitHint,                \
                    SsSsh* pSsSsh                        \
                    )
{/* Устанавливаем статус сервиса */
    /* Инициализация контрольной точки */
    static DWORD dwCheckPoint=1;
    /* Забираем данные о состоянии сервиса */
    SERVICE_STATUS ss=(*(pSsSsh)).ss;
    SERVICE_STATUS_HANDLE ssh=(*(pSsSsh)).ssh;
    /* Если сервер запускается */
    if(dwCurrentState == SERVICE_START_PENDING)
        ss.dwControlsAccepted=0;
    else/* Любой другой случай */
        ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;

    ss.dwCurrentState=dwCurrentState;
    ss.dwWin32ExitCode=dwWin32ExitCode;
    ss.dwWaitHint=dwWaitHint;
    /* Если сервис закончил запуск или остановку, сброс контрольной точки */
    if( (dwCurrentState == SERVICE_RUNNING) ||        \
        (dwCurrentState == SERVICE_STOPPED)                \
        )
        ss.dwCheckPoint=0;
    else/* Иначе -- инкрементируем контрольную точку */
        ss.dwCheckPoint=dwCheckPoint++;
    /* И отдаём изменённые данные диспетчеру сервисов */
    ::SetServiceStatus(ssh,&ss);
}
//-------------------------------------------------------------------------
DWORD WINAPI HandlerEx(DWORD dwControl,DWORD dwEventType,        \
                     LPVOID lpEventData,LPVOID lpContext    \
                     )
{/* Обработчик сигналов управления сервисом */
    /* Принимаем данные о состоянии сервиса */
    SsSsh ssssh=*((SsSsh*)lpContext);
    switch(dwControl)
    {
        /* Если система выключается */
    case SERVICE_CONTROL_SHUTDOWN:
        /* Или останавливается сервис */
    case SERVICE_CONTROL_STOP:
        {
            /* Статус сервиса -- "В процессе остановки" */
            SetSomeServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,&ssssh);
            /* Останавливаем поток */
            ::SetEvent(hControlEvent);
            while(::WaitForSingleObject(hControlEvent,0) == WAIT_OBJECT_0)
            { Sleep(0); }
            /* Статус сервиса -- "Остановлен" */
            SetSomeServiceStatus(SERVICE_STOPPED,NO_ERROR,0,&ssssh);
            break;
        }
    case SERVICE_CONTROL_INTERROGATE:
        {/* Опрос текущего состояния сервиса */
            SetSomeServiceStatus(ssssh.ss.dwCurrentState,NO_ERROR,0,&ssssh);
            break;
        }
        default:
        {
            SetSomeServiceStatus(ssssh.ss.dwCurrentState,NO_ERROR,0,&ssssh);
            break;
        }
    }
    return 0;
}
//-------------------------------------------------------------------------
VOID WINAPI ServiceMain(DWORD dwArgc,LPTSTR* lpszArgv)
{
    SsSsh ssssh;
    SERVICE_STATUS ss;
    /* Регистрируем функцию-обработчик сигналов к сервису, передаём
         ей имя сервиса, собственно, указатель на обработчик и контекст */
    SERVICE_STATUS_HANDLE    ssh=RegisterServiceCtrlHandlerEx(WebPrice,            \
                                                     &HandlerEx,        \
                                                     (VOID*)&ssssh    \
                                                     );
    /* Сервисом будет обычный процесс */
    ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
    /* Начальное состояние -- в процессе запуска */
    ss.dwCurrentState=SERVICE_START_PENDING;///
    /* Отслеживает остановку и выключение системы */
    ss.dwControlsAccepted=SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    /* Не сообщаем об ошибках */
    ss.dwWin32ExitCode=NO_ERROR;
    /**/
    ss.dwServiceSpecificExitCode=0;///
    /* Начинаем отсчёт запуска */
    ss.dwCheckPoint=1;//0
    /* Если через 5 сек. dwCheckPoint не инкрементируется -- проблемы */
    ss.dwWaitHint=5000;//0
    /* Собираем данные в кучу */
    ssssh.ss=ss;
    ssssh.ssh=ssh;
    /**/
    SetSomeServiceStatus(SERVICE_START_PENDING,NO_ERROR,4000,&ssssh);
    FILE* file=fopen("E:\\ZZZ.txt","a");
    if(file == NULL)
        return;
    SetSomeServiceStatus(SERVICE_RUNNING,NO_ERROR,0,&ssssh);
    // main program code
    while(::WaitForSingleObject(hControlEvent,0) != WAIT_OBJECT_0)
    {
        fwrite("test\n",1,5,file);
        fflush(file);
        Sleep(30000);
    }
    fwrite("\0",1,2,file);
    fflush(file);
    fclose(file);
    ::ResetEvent(hControlEvent);
    ::CloseHandle(hControlEvent);
    return;
}
//-------------------------------------------------------------------------
INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,    \
                 LPSTR lpCmdLine,int nCmdShow            \
                 )
{
    /* Если не удалось создать управляющее событие -- огорчение */
    if((hControlEvent=::CreateEvent(NULL,TRUE,FALSE,NULL)) == NULL)
        return -1;
    SERVICE_TABLE_ENTRY DispatcherTable[]=
        {/* Описание запускаемых сервисов */
            {WebPrice,(LPSERVICE_MAIN_FUNCTION)ServiceMain},
            {NULL,NULL}
        };
    /* Запуск сервисов */
    ::StartServiceCtrlDispatcher(DispatcherTable);
    return 0;
}


А это -- заголовочный файл к нему

Код

#ifndef SERVICE_H_20070910_1251
#define SERVICE_H_20070910_1251

#define WebPrice "WebPrice"
extern DWORD WINAPI EntryPoint(LPVOID lpParam);
extern HMODULE g_module;

#endif


ВотЪ, Makefile, на всякий случай...

Код

REMOVE = rm -f
SRCINSTALL = install
SRCUNINSTALL = uninstall
SRCMAIN = service
SRCMAINHEADER = service
OUTINSTALL = $(SRCINSTALL)
OUTUNINSTALL = $(SRCUNINSTALL)
OUTMAIN = service

$(OUTINSTALL) : $(SRCINSTALL).o
    g++ -o $(OUTINSTALL) $(SRCINSTALL).o
$(SRCINSTALL).o : $(SRCINSTALL).cpp
    g++ -c -Os -Wall $(SRCINSTALL).cpp
    strip --strip-debug $(SRCINSTALL).o
$(OUTUNINSTALL) : $(SRCUNINSTALL).o
    g++ -o $(OUTUNINSTALL) $(SRCUNINSTALL).o
$(SRCUNINSTALL).o : $(SRCUNINSTALL).cpp
    g++ -c -Os -Wall $(SRCUNINSTALL).cpp
    strip --strip-debug $(SRCUNINSTALL).o
$(OUTMAIN) : $(SRCMAIN).o
    g++ -o $(OUTMAIN) $(SRCMAIN).o
$(SRCMAIN).o : $(SRCMAIN).cpp $(SRCMAINHEADER).h
    g++ -c -Os -Wall $(SRCMAIN).cpp
    strip --strip-debug $(SRCMAIN).o

exe_install :
    $(MAKE) $(OUTINSTALL)
exe_uninstall :
    $(MAKE) $(OUTUNINSTALL)
exe_main :
    $(MAKE) $(OUTMAIN)
clean_install :
    $(REMOVE) $(OUTINSTALL).exe
    $(REMOVE) $(SRCINSTALL).o
clean_uninstall :
    $(REMOVE) $(OUTUNINSTALL).exe
    $(REMOVE) $(SRCUNINSTALL).o
clean_main :
    $(REMOVE) $(OUTMAIN).exe
    $(REMOVE) $(SRCMAIN).o
clean :
    $(REMOVE) $(wildcard *.exe)
    $(REMOVE) $(wildcard *.o)
help :
    @echo clean exe_install exe_uninstall exe_main
ALL : clean exe_install exe_uninstall exe_main


Тут несколько коряво всё сделано, конечно, зато работает!

Это сообщение отредактировал(а) EnergoHokum - 25.3.2008, 08:38
PM MAIL ICQ   Вверх
alt_7
Дата 29.3.2008, 19:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 11
Регистрация: 12.5.2007

Репутация: нет
Всего: нет



Спасибо за ответ, попробую разобраться.
PM MAIL   Вверх
EnergoHokum
Дата 24.4.2008, 12:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 600
Регистрация: 10.11.2006
Где: Россия, Ставропол ь

Репутация: 3
Всего: 6



После длительных (дня три) разборок с вышенаписанным текстом пришёл к выводу, что он -- гуано. Выкладываю новую версию service.cpp:

Код

#include <cstdio>
#include <cstring>
#include <windows.h>
#include "service.h"
//-------------------------------------------------------------------------
/* Упреждающее объявление WinMain */
extern "C" INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,    \
                        LPSTR lpCmdLine,int nCmdShow            \
                              );
//-------------------------------------------------------------------------
/* Управляющее событие */
HANDLE hControlEvent;
/* Текущий статус сервиса */
SERVICE_STATUS ss;
/* Handle для структуры статуса */
SERVICE_STATUS_HANDLE ssh;
/* Объединяем в одну структуру для возможности передачи указателя на неё */
struct SsSsh { SERVICE_STATUS ss; SERVICE_STATUS_HANDLE ssh; };
//-------------------------------------------------------------------------
VOID SetSomeServiceStatus(SsSsh* pSsSsh)
{/* Устанавливаем статус сервиса */
    char str0[]="\'dwCheckPoint\' incremented";
    FILE* file=fopen("E:\\z__SetSomeServiceStatus.txt","a");
    /* Если сервис закончил запуск или остановку, сброс контрольной точки */
    if( (pSsSsh->ss.dwCurrentState == SERVICE_RUNNING) ||        \
        (pSsSsh->ss.dwCurrentState == SERVICE_STOPPED)            \
        )
    {
        pSsSsh->ss.dwCheckPoint=0;
    }
    else/* Иначе -- инкрементируем контрольную точку */
    {
        ++pSsSsh->ss.dwCheckPoint;
        fprintf(file,"%s, value is %li\n",str0,pSsSsh->ss.dwCheckPoint);
        fclose(file);
    }
    /* И отдаём изменённые данные диспетчеру сервисов */
    ::SetServiceStatus(pSsSsh->ssh,&pSsSsh->ss);
}
//-------------------------------------------------------------------------
DWORD WINAPI HandlerEx(DWORD dwControl,DWORD dwEventType,        \
                     LPVOID lpEventData,LPVOID lpContext    \
                       )
{/* Обработчик сигналов управления сервисом */
    /* Принимаем данные о состоянии сервиса */
    switch(dwControl)
    {
        /* Если система выключается */
    case SERVICE_CONTROL_SHUTDOWN:
        /* Или останавливается сервис */
    case SERVICE_CONTROL_STOP:
        {
            /* Разрешаем запуск потока, пинающего SCM */
            ::SetEvent(hControlEvent);
            break;
        }
        /* Если происходит опрос состояния сервиса */
    case SERVICE_CONTROL_INTERROGATE:
        {
            /* Отдаём текущее состояние */
            SetSomeServiceStatus((SsSsh*)lpContext);
            break;
        }
        /* Любое другое управляющее событие */
    default:
        {
            /* Отдаём текущее состояние */
            SetSomeServiceStatus((SsSsh*)lpContext);
            break;
        }
    }
    return 0;
}
//-------------------------------------------------------------------------
DWORD WINAPI CheckPointInc(LPVOID lpVoid)
{/* Функция потока, пинающего SCM при остановке */
    /* Устанавливаем свойство "Сервис в процессе остановки" */
    ((SsSsh*)lpVoid)->ss.dwCurrentState=SERVICE_STOP_PENDING;
    /* Ждём, пока ServiceMain не взведёт событие hControlEvent */
    while(::WaitForSingleObject(hControlEvent,0) != WAIT_OBJECT_0)
    {
        /* А пока периодически пинаем SCM */
        SetSomeServiceStatus((SsSsh*)lpVoid);
        /* Отдохнём перед следующим пинком */
        ::Sleep(5000);
    }
    /* ServiceMain готова к полной остановке, подтверждаем */
    ::ResetEvent(hControlEvent);
    return 0;
}
//-------------------------------------------------------------------------
VOID WINAPI ServiceMain(DWORD dwArgc,LPTSTR* lpszArgv)
{
    SsSsh ssssh;
    /* Регистрируем функцию-обработчик сигналов к сервису, передаём
         ей имя сервиса, собственно, указатель на обработчик и контекст */
    ssssh.ssh=RegisterServiceCtrlHandlerEx(WebPrice,            \
                                     &HandlerEx,        \
                                     (VOID*)&ssssh    \
                                     );
    /* Сервисом будет обычный процесс */
    ssssh.ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
    /* Начальное состояние -- в процессе запуска */
    ssssh.ss.dwCurrentState=SERVICE_START_PENDING;///
    /* Отслеживает остановку и выключение системы */
    ssssh.ss.dwControlsAccepted=SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
    /* Не сообщаем об ошибках */
    ssssh.ss.dwWin32ExitCode=NO_ERROR;
    ssssh.ss.dwServiceSpecificExitCode=0;///
    /* Начинаем отсчёт запуска */
    ssssh.ss.dwCheckPoint=0;//0
    /* Если через 10 сек. dwCheckPoint не инкрементируется -- проблемы */
    ssssh.ss.dwWaitHint=10000;//0
    /* Установим это состояние для сервиса */
    SetSomeServiceStatus(&ssssh);
    // main program code
    FILE* file=fopen("E:\\z__ZZZ.txt","a");
    if(file == NULL)
    {/* Не получилось открыть/создать файл -- огорчение */
        ssssh.ss.dwCurrentState=SERVICE_STOPPED;
        SetSomeServiceStatus(&ssssh);
        return;
    }
    /* Сервис запущен */
    ssssh.ss.dwCurrentState=SERVICE_RUNNING;
    SetSomeServiceStatus(&ssssh);
    /* Ждём, пока HandlerEx не пришлёт собы-
         тие останова или выключения питания */
    while(::WaitForSingleObject(hControlEvent,0) != WAIT_OBJECT_0)
    {
        fwrite("test\n",1,strlen("test\n"),file);
        fflush(file);
        ::Sleep(1500);
    }
    /* Сбросим это событие */
    ::ResetEvent(hControlEvent);
    /* Создаём поток, пинающий SCM */
    HANDLE hTh=::CreateThread(NULL,0,CheckPointInc,(LPVOID)&ssssh,0,NULL);
    /* Здесь выполняются длительные действия по остановка сер-
         виса (но не более 120 сек., почему -- пока не знаю) */
    ::Sleep(110000);
    fwrite("\nSuccess stop\n",1,strlen("\nSuccess stop\n"),file);
    /* Подготовка к останову завершена, можно прервать пинающий поток */
    ::SetEvent(hControlEvent);
    /* Теперь ждём, пока завершится пинающий поток */
    while(::WaitForSingleObject(hControlEvent,0) == WAIT_OBJECT_0)
    { ::Sleep(5); }
    /* Сбросим событие */
    ::ResetEvent(hControlEvent);
    fflush(file);
    fclose(file);
    /* Сервис полностью остановлен, */
    ssssh.ss.dwCurrentState=SERVICE_STOPPED;
    /* сообщаем об этом SCM-у */
    SetSomeServiceStatus(&ssssh);
    return;
}
//-------------------------------------------------------------------------
INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,    \
                                     LPSTR lpCmdLine,int nCmdShow            \
                                     )
{
    /* Если не удалось создать управляющее событие -- огорчение */
    if((hControlEvent=::CreateEvent(NULL,TRUE,FALSE,"Control")) == NULL)
        return -1;
    /* На всякий случай сбросим его (или у меня паранойя?) */
    ::ResetEvent(hControlEvent);
    SERVICE_TABLE_ENTRY DispatcherTable[]=
        {/* Описание запускаемых сервисов */
            {WebPrice,(LPSERVICE_MAIN_FUNCTION)ServiceMain},
            {NULL,NULL}
        };
    /* Запуск сервисов */
    ::StartServiceCtrlDispatcher(DispatcherTable);
    return 0;
}


Прошлая версия была практически полностью неработоспособна. Проблема этой версии -- не получается выделить время на остановку более 120 секунд. Сам сервис корректно останавливается и при бОльших временах, но через 120 сек. выскакивает сообщение (от SCM, как я понимаю), что сервис не отвечает, и вообще всё плохо (злой и жестокий мир...). Пока такое поведение забороть мне не удалось. Но в диапазоне от 0 и до 120 сек. -- работает корректно. Кроме одного: при первом запуске свежескомпилированной программы попытка остановить её приводит к такому-же сообщению мгновенно. Последующие запуски/остановки происходят корректно. Как только разберусь в причинах -- отпишусь.
PM MAIL ICQ   Вверх
sawka88
Дата 6.5.2010, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



Ребят, подскажите пожалуйста, есть ли у кого пример полностью рабочей службы?
Очень надо!
Предложенный выше пример по моим пробам работает не до конца корректно.
Ещё один вопрос: Представленный выше пример компилируется только начиная с 2005 Visual Studio, 6-я же жалуется на то, что не знает функции RegisterServiceCtrlHandlerEx.
На сколько я понимаю, если я скомпилирую данную службу на 2005, то для ее работы понадобится .NET Frimework или я ошибаюсь?
Мне нужно чтобы служба работала на голой винде, без установки каких либо дополнений.
Заранее благодарен за все ответы!
PM MAIL   Вверх
smoke_man
Дата 7.5.2010, 07:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 447
Регистрация: 25.1.2007
Где: Рязань

Репутация: 5
Всего: 17



Если нужна служба на Builder, то посмотри пример тут, правда рассматривается на Delphi, но суть таже.


--------------------
0x2b|~0x2b
PM MAIL ICQ GTalk   Вверх
xvr
Дата 7.5.2010, 11:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 40
Всего: 223



Цитата(sawka88 @  6.5.2010,  22:56 Найти цитируемый пост)
Предложенный выше пример по моим пробам работает не до конца корректно.
Чем именно не корректно?
Цитата

На сколько я понимаю, если я скомпилирую данную службу на 2005, то для ее работы понадобится .NET Frimework 
Если тип проекта был Win32 (с любой разновидностью), то не понадобится

PM MAIL   Вверх
sawka88
Дата 9.5.2010, 14:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 4
Регистрация: 26.4.2008

Репутация: нет
Всего: нет



А нет ли у кого рабочего примера под visual studio 6.0?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0724 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.