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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> сервис 
:(
    Опции темы
lavan
Дата 21.4.2011, 18:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



возник вопрос по созданию служб может кто сможет помочь?.Для создания процесса с одним сервисом,надо иметь 3 
функции:main,servicemain,servicehandle.написал,получаю ошибку:служба запускается как приложение
(ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)в мэйн не использовались такие функции как:OpenSCManager,CreateService.
исправил это так:sc create
теперь сервис отображается в окне служб,но после того как я нажимаю старт,сервис вроде как запускается,но ничего не делает
люди не поленитесь,расскажите пошагово как это работает!!!!!
Код

#include<windows.h>
#include<iostream>
#include<fstream>
using namespace std;
static SERVICE_STATUS hs;
static SERVICE_STATUS_HANDLE hstat;
void WINAPI sermain(DWORD argc,LPTSTR argv[]);
void WINAPI serctrlh(DWORD dwcontrol);
LPTSTR sername=_T("MY_TEST");
ofstream out;
int count;
int main() {
SERVICE_TABLE_ENTRY tab[]={{sername,sermain},{NULL,NULL}};
DWORD check;
if(!StartServiceCtrlDispatcher(tab)) {
 check=GetLastError();
 if(check==ERROR_FAILED_SERVICE_CONTROLLER_CONNECT)
 cout<<"1";
 else if(check==ERROR_INVALID_DATA)
 cout<<"2";
 else if(check==ERROR_SERVICE_ALREADY_RUNNING)
 cout<<"3";
cout<<"\nbug1";
cin.get();
}
return 0;
}
void WINAPI sermain(DWORD argc,LPTSTR argv[]) {
hstat=RegisterServiceCtrlHandler(sername,serctrlh);
if(!hstat) {
out.open("serfile.txt");
if(!out) {
    cout<<"bf1";
    cin.get();
    return;
}
out<<"bug regeterhandle\n";
out.close();
return;
}
hs.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
  hs.dwCurrentState=SERVICE_START_PENDING;
  hs.dwControlsAccepted=SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
  hs.dwWin32ExitCode=0;
  hs.dwServiceSpecificExitCode=0;
  hs.dwCheckPoint=0;
  hs.dwWaitHint=5000;
//устанавливаем состояние сервиса
if(!SetServiceStatus(hstat,&hs)) {
out.open("serfile.txt");
if(!out) {
    cout<<"bf2";
    cin.get();
    return;
}
out<<"bug servicestatus 1\n";
out.close();
return;
}
//определяем сервис как работающий
hs.dwCurrentState=SERVICE_RUNNING;
//нет ошибок
hs.dwWin32ExitCode=NO_ERROR;
if(!SetServiceStatus(hstat,&hs)) {
out.open("serfile.txt");
if(!out) {
    cout<<"bug3";
    cin.get();
    return;
}
out<<"bug servicestatus 2\n";
out.close();
return;
}
out.open("serfile.txt");
if(!out) {
    cout<<"bug4";
    cin.get();
    return;
}
out<<"ser is started\n"<<"name is "<<argv[0]<<endl;
//work cicle of service

while(hs.dwCurrentState==SERVICE_RUNNING) {
count++;
Sleep(100);
}

}
void WINAPI serctrlh(DWORD dwcontrol) {


switch(dwcontrol) {
case SERVICE_CONTROL_STOP:
out<<"count="<<count<<endl;
out.close();
hs.dwCurrentState=SERVICE_STOPPED;
SetServiceStatus(hstat,&hs);
break;
case SERVICE_CONTROL_SHUTDOWN:
hs.dwCurrentState=SERVICE_STOPPED;
SetServiceStatus(hstat,&hs);
break;
}
return;
}


PM MAIL   Вверх
xvr
Дата 22.4.2011, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(lavan @  21.4.2011,  18:44 Найти цитируемый пост)
,сервис вроде как запускается,но ничего не делает
люди
Ну так - что просили, то он и делает  smile 

Цитата

Код

while(hs.dwCurrentState==SERVICE_RUNNING) {
count++;
Sleep(100);
}



Цитата(lavan @  21.4.2011,  18:44 Найти цитируемый пост)
люди не поленитесь,расскажите пошагово как это работает!!!!!

В смысле - я тут написал, объясните мне, что именно я написал?  smile 
http://msdn.microsoft.com/en-us/library/ms...v=VS.85%29.aspx

PM MAIL   Вверх
lavan
Дата 22.4.2011, 13:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



весь ваш комент xvr не потеме,прога рабочая,ошибка была в том,что надо было прописывать полный путь к создаваемому лог файлу,и сначало я не понял что через консоль- Службы, при нажатии на старт,автоматически вызываются OpenSCManager(),StartService()
Цитата(xvr @  22.4.2011,  12:48 Найти цитируемый пост)
Ну так - что просили, то он и делает   

вы наверно не стали себя утруждать просмотром кода!потому что код,как минимум должен был создать файл!
PM MAIL   Вверх
xvr
Дата 23.4.2011, 07:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(lavan @ 22.4.2011,  13:55)
весь ваш комент xvr не потеме,прога рабочая,

Если бы вы внятно сказали, что вы ожидаете от своего сервиса, вам бы ответили. А так - какой вопрос, такой и ответ  smile 
Цитата

вы наверно не стали себя утруждать просмотром кода!потому что код,как минимум должен был создать файл!
Он его создает. В папке windows\system32.  (Или в windows - навскидку не скажу).
Цитата

ошибка была в том,что надо было прописывать полный путь к создаваемому лог файлу,
Т.е. вы считаете, что тут все телепаты и должны были догадаться, что вам лог файл нужен был не в системной папке?  smile 
И код я ваш посмотрел - он ужасен  smile 

PM MAIL   Вверх
borisbn
Дата 23.4.2011, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(lavan @  22.4.2011,  13:55 Найти цитируемый пост)
вы наверно не стали себя утруждать просмотром кода!

ВаШкОдНаСтОлЬкОсЛоЖнОчИтАтЬчТоНеТнИкАкОгОжЕлАнИяЭтОдЕлАтЬпОтРуДиТеСьЕгОоТфОрМаТиРоВаТьДлЯнАчАлА

lavan, приятно ?


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
lavan
Дата 27.4.2011, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



xvr, все ваши комментарии принимаются,не правильная постановка вопроса от непонимания темы!а на счет кода,обычный код для проверки!
borisbn,а как вы видете нормально оформленный код???
попробую задать более четкий вопрос.написал прогу(запускаю кликом по проге)
часть программы:
Код

int main(){
scmanager=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
          if(!scmanager) {
                  return 0;
          }
          if(!GetModuleFileName(NULL,path,256)) {
          return 0;
          }
          if((ser=OpenService(scmanager,MT,SERVICE_ALL_ACCESS))==NULL) {
          service=CreateService(scmanager,MT,sername,NULL,
          SERVICE_WIN32_OWN_PROCESS,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,
          path,NULL,NULL,NULL,NULL,NULL);
          if(!service) {
                  return 0;
          }
          }
          if(ser) {
          StartService(ser,0,0);
          CloseServiceHandle(ser);
          CloseServiceHandle(scmanager);
          }
          else {
          StartService(service,0,0);
          CloseServiceHandle(service);
          CloseServiceHandle(scmanager);
          }
          SERVICE_TABLE_ENTRY tab[]={{MT,servicemain},{NULL,NULL}};
          DWORD check;
if(!StartServiceCtrlDispatcher(tab)) {
                  return 0;
          }
          return 0;
}

выскакивает ошибка:сервис запускается как приложение
но,сервис находится в консоли Службы и через эту консоль его можно запустить.
КАК ИЗБАВИТЬСЯ ОТ ЭТОЙ ОШИБКИ???? 
ели использовать аргументы ком строки то
Код

int main(int argc,char *argv[]) {
if(!strcpm(argv[1],"start")
//вызываем фун которая вызовет OpenSCManager,CreateService,SartService после отработки
....
//попали сюда а здесь сново
StartCtrlDispatchar(...)
//И БУДЕТ ТА ЖА ОШИБКА!если нет,объясните почему?
}

PM MAIL   Вверх
borisbn
Дата 27.4.2011, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(lavan @  27.4.2011,  18:03 Найти цитируемый пост)
borisbn,а как вы видете нормально оформленный код???

было
Код

void WINAPI serctrlh(DWORD dwcontrol) {


switch(dwcontrol) {
case SERVICE_CONTROL_STOP:
out<<"count="<<count<<endl;
out.close();
hs.dwCurrentState=SERVICE_STOPPED;
SetServiceStatus(hstat,&hs);
break;
case SERVICE_CONTROL_SHUTDOWN:
hs.dwCurrentState=SERVICE_STOPPED;
SetServiceStatus(hstat,&hs);
break;
}
return;
}

хотелось бы ( чтоб не разбирать как каракули у врачей smile )
Код

void WINAPI serctrlh(DWORD dwcontrol) {
    switch(dwcontrol) {
        case SERVICE_CONTROL_STOP:
            out << "count=" << count << endl;
            out.close();
            hs.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus(hstat,&hs);
        break;
        case SERVICE_CONTROL_SHUTDOWN:
            hs.dwCurrentState = SERVICE_STOPPED;
            SetServiceStatus(hstat,&hs);
        break;
    }
    return;
}



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
xvr
Дата 27.4.2011, 19:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(lavan @  27.4.2011,  18:03 Найти цитируемый пост)
КАК ИЗБАВИТЬСЯ ОТ ЭТОЙ ОШИБКИ????

Никак. Сервис (именно как сервис) может быть запущен только системой, и только при таком запуске функция StartServiceCtrlDispatcher будет работать.
Собственно в сервисах есть 2 совершенно независимых части - регистрация и управление сервисом (это OpenSCManager и все, что от него растет). И сам сервис - это StartServiceCtrlDispatcher  и все что от него растет.
Управление - это обычное приложение, оно даже не обязано содержаться в том же exe, что и сам сервис (StartServiceCtrlDispatcher). 
Собственно 'консоли Службы' этим интерфейсом и пользуется

Сам сервис же запускается (по команде из 1й части) специальным системным процессом (servises.exe)

Собственно, когда вы вызываете StartService из своей программы (той, что два в одном  smile ), то сервис мэнеджер (servises.exe) запускает 2й экземпляр вашей программы, который и становится сервисом, а 1й экземпляр (тот, что вызывал StartService) завершается

PM MAIL   Вверх
ASMatic
Дата 29.4.2011, 03:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



не особо там вычитывая но понимая траблу с сервисаме)
Код

#define SERVICE_NAME        L"TestService"
#define DEFAULT_HINT_TIME   3000

SERVICE_STATUS          SvcStatus;
SERVICE_STATUS_HANDLE   hSvcStatus;
HANDLE                  hMainSvcThread;

INT
main(
    VOID
    )
{
    SERVICE_TABLE_ENTRY     SvcEntries[2] = { 0 };

    SvcEntries[0].lpServiceName = SERVICE_NAME;
    SvcEntries[0].lpServiceProc = ServiceMain;

    if (!StartServiceCtrlDispatcher( SvcEntries )) {
        return SVC_ERROR;
    }

    return NO_ERROR;
}

VOID
WINAPI
ServiceMain(
    IN      DWORD   dwArgc,
    IN      LPTSTR  *lpszArgv
    )
{
    hSvcStatus = RegisterServiceCtrlHandlerEx( NULL,
                                               (LPHANDLER_FUNCTION_EX)SvcHandlerEx,
                                               NULL );
    if (hSvcStatus == NULL)
        return;

    //
    //Fill service status struct
    //
    SvcStatus.dwCheckPoint = 0;
    SvcStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SESSIONCHANGE;
    SvcStatus.dwServiceSpecificExitCode = 0;
    SvcStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    SvcStatus.dwWaitHint = DEFAULT_HINT_TIME;
    SvcStatus.dwWin32ExitCode = NO_ERROR;

    ReportSvcStatus( SERVICE_START_PENDING );

    ServiceInit();
}

VOID
ReportSvcStatus(
    IN      DWORD   CurrentState
    )
{
    ReportSvcStatusEx( CurrentState,
                       NO_ERROR,
                       DEFAULT_HINT_TIME );
}

VOID
ReportSvcStatusEx(
    IN      DWORD   CurrentState,
    IN      DWORD   Win32ExitCode,
    IN      DWORD   WaitHint
    )
{
    static DWORD    CheckPoint = 1;

    SvcStatus.dwCurrentState = CurrentState;
    SvcStatus.dwWin32ExitCode = Win32ExitCode;
    SvcStatus.dwWaitHint = WaitHint;

    /*
    //if don`t use CheckPoints this bite of code can be deleted
    if ( (CurrentState == SERVICE_RUNNING) || (CurrentState == SERVICE_STOPPED) )
        SvcStatus.dwCheckPoint = 0;
    else
        SvcStatus.dwCheckPoint = CheckPoint++;
    */

    //Report SCM
    SetServiceStatus( hSvcStatus,
                      &SvcStatus );
}

VOID
WINAPI
SvcHandlerEx(
    IN      DWORD   Control,
    IN      DWORD   EventType,
    IN      LPVOID  EventData,
    IN      LPVOID  Context
    )
{
    DWORD   State;

    switch (Control) {

        case SERVICE_CONTROL_STOP:
            ReportSvcStatus( SERVICE_STOPPED );
            return;

        default:
            State = SERVICE_RUNNING;
    }

    ReportSvcStatus( State );
}

VOID
ServiceInit(
    VOID
    )
{
    DWORD   result;

    result = SafeCreateThread( &hMainSvcThread,
                               MainSvcThread,
                               NULL );
    if (result != NO_ERROR) {
        StopService( NULL,
                     0 );
    }

    SvcStatus.dwWaitHint = 0;
    SvcStatus.dwCheckPoint = 0;
    ReportSvcStatus( SERVICE_RUNNING );
}

VOID
StopService(
    IN      PWCHAR  Event,
    IN      DWORD   ErrorCode
    )
{
    ReportSvcStatus( SERVICE_STOP );
    ExitProcess( ErrorCode );
}

DWORD
WINAPI
MainSvcThread(
    IN      PVOID   Parameter
    )
{
    return NO_ERROR;
}


РАБОЧИЙ СЕРВИС! - инсталь и юзай.)
*есессно код для тестов.
PM MAIL   Вверх
lavan
Дата 1.5.2011, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Всем спасибо за помощь,вроде разобрался!
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.0537 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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