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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Windows Service не стартует 
V
    Опции темы
freezeman
Дата 26.2.2012, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Всем привет!

Подскажите, пожалуйста, почему служба не запускается? Код проходит без ошибок, но проверяю диспетчер служб и не нахожу созданную службу...

Код:
Код

#include "stdafx.h"
#include <windows.h>
#include <winsvc.h>

void ServiceMain(DWORD argc, LPTSTR *argv); 
void ServiceCtrlHandler(DWORD nControlCode);
BOOL UpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
                     DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
                     DWORD dwWaitHint);
BOOL StartServiceThread();
DWORD ServiceExecutionThread(LPDWORD param);
HANDLE hServiceThread;
void KillService();

char *strServiceName = "NishFirstService";
SERVICE_STATUS_HANDLE nServiceStatusHandle; 
HANDLE killServiceEvent;
BOOL nServiceRunning;
DWORD nServiceCurrentStatus;

void main(int argc, char* argv[])
{
    SERVICE_TABLE_ENTRY servicetable[]=
    {
        {(LPWSTR)strServiceName,
        (LPSERVICE_MAIN_FUNCTION)ServiceMain},
        {NULL,NULL}
    };
    BOOL success;
    success=StartServiceCtrlDispatcher(servicetable);
    if(!success)
    {
        //error occured
    }
}

void ServiceMain(DWORD argc, LPTSTR *argv)
{
    BOOL success;
    nServiceStatusHandle=RegisterServiceCtrlHandler(
        (LPWSTR)strServiceName,
        (LPHANDLER_FUNCTION)ServiceCtrlHandler);
    if(!nServiceStatusHandle)
    {
        return;
    }
    success=UpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,1,3000);
    if(!success)
    {
        return;
    }
    killServiceEvent=CreateEvent(0,TRUE,FALSE,0);
    if(killServiceEvent==NULL)
    {
        return;
    }
    success=UpdateServiceStatus(SERVICE_START_PENDING,NO_ERROR,0,2,1000);
    if(!success)
    {
        return;
    }
    success=StartServiceThread();
    if(!success)
    {
        return;
    }
    nServiceCurrentStatus=SERVICE_RUNNING;
    success=UpdateServiceStatus(SERVICE_RUNNING,NO_ERROR,0,0,0);
    if(!success)
    {
        return;
    }
    WaitForSingleObject(killServiceEvent,INFINITE);
    CloseHandle(killServiceEvent);
}



BOOL UpdateServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode,
                     DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
                     DWORD dwWaitHint)
{
    BOOL success;
    SERVICE_STATUS nServiceStatus;
    nServiceStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
    nServiceStatus.dwCurrentState=dwCurrentState;
    if(dwCurrentState==SERVICE_START_PENDING)
    {
        nServiceStatus.dwControlsAccepted=0;
    }
    else
    {
        nServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP            
            |SERVICE_ACCEPT_SHUTDOWN;
    }
    if(dwServiceSpecificExitCode==0)
    {
        nServiceStatus.dwWin32ExitCode=dwWin32ExitCode;
    }
    else
    {
        nServiceStatus.dwWin32ExitCode=ERROR_SERVICE_SPECIFIC_ERROR;
    }
    nServiceStatus.dwServiceSpecificExitCode=dwServiceSpecificExitCode;
    nServiceStatus.dwCheckPoint=dwCheckPoint;
    nServiceStatus.dwWaitHint=dwWaitHint;

    success=SetServiceStatus(nServiceStatusHandle,&nServiceStatus);

    if(!success)
    {
        KillService();
        return success;
    }
    else
        return success;
}

BOOL StartServiceThread()
{    
    DWORD id;
    hServiceThread=CreateThread(0,0,
        (LPTHREAD_START_ROUTINE)ServiceExecutionThread,
        0,0,&id);
    if(hServiceThread==0)
    {
        return false;
    }
    else
    {
        nServiceRunning=true;
        return true;
    }
}

DWORD ServiceExecutionThread(LPDWORD param)
{
    while(nServiceRunning)
    {        
        Beep(450,150);
        Sleep(4000);
    }
    return 0;
}

void KillService()
{
    nServiceRunning=false;
    SetEvent(killServiceEvent);
    UpdateServiceStatus(SERVICE_STOPPED,NO_ERROR,0,0,0);
}

void ServiceCtrlHandler(DWORD nControlCode)
{
    BOOL success;
    switch(nControlCode)
    {    
    case SERVICE_CONTROL_SHUTDOWN:
    case SERVICE_CONTROL_STOP:
        nServiceCurrentStatus=SERVICE_STOP_PENDING;
        success=UpdateServiceStatus(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000);
        KillService();        
        return;
    default:
        break;
    }
    UpdateServiceStatus(nServiceCurrentStatus,NO_ERROR,0,0,0);
}



При StartServiceCtrlDispatcher выдает ошибку 1063!!!

Это сообщение отредактировал(а) freezeman - 26.2.2012, 15:29
PM MAIL   Вверх
freezeman
Дата 26.2.2012, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Подскажите, в чем может быть проблема? Именно при запуске (StartServiceCtrlDispatcher) выдает ошибку. Пробовал как на XP x86, так и на Win 7 x86.
Error 1063
PM MAIL   Вверх
feodorv
Дата 26.2.2012, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(freezeman @  26.2.2012,  13:35 Найти цитируемый пост)
void ServiceMain(DWORD argc, LPTSTR *argv)

Может, 
Цитата

VOID WINAPI ServiceMain(...)

Хотя 
Цитата(freezeman @  26.2.2012,  15:38 Найти цитируемый пост)
Error 1063 
 не об этом.

Ну и
Цитата(freezeman @  26.2.2012,  13:35 Найти цитируемый пост)
        {(LPWSTR)strServiceName,

Может, (LPТSTR)...?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
freezeman
Дата 26.2.2012, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(feodorv @ 26.2.2012,  16:30)
Цитата(freezeman @  26.2.2012,  13:35 Найти цитируемый пост)
void ServiceMain(DWORD argc, LPTSTR *argv)

Может, 
Цитата

VOID WINAPI ServiceMain(...)

Хотя 
Цитата(freezeman @  26.2.2012,  15:38 Найти цитируемый пост)
Error 1063 
 не об этом.

Ну и
Цитата(freezeman @  26.2.2012,  13:35 Найти цитируемый пост)
        {(LPWSTR)strServiceName,

Может, (LPТSTR)...?

Спасибо за ответ! Я решил взять пример здесь, все прекрасно описывается.

Но не могу теперь найти место, где выполнять мой код!! Может звучит глупо, но, как я понимаю, он должен располагаться в ServiceMain, пытаюсь вывести что-нибудь в файл, но ничего происходит... 

Прикрепил проект!

Для запуска необходимо в командной строке указать ключ -install и запустить службу.

Добавлено через 5 минут и 13 секунд
Небольшая поправка, мой код выполняется в ServiceMain только после перезапуска или остановки службы (т.е. когда я запустил службу ничего не произошло, но после её остановки или перезапуска код начинает выполняться и пишет в файл)

Каким это образом может происходить???

Присоединённый файл ( Кол-во скачиваний: 7 )
Присоединённый файл  minsvc.zip 9,65 Kb
PM MAIL   Вверх
feodorv
Дата 26.2.2012, 18:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(freezeman @  26.2.2012,  18:21 Найти цитируемый пост)
т.е. когда я запустил службу 

А каки образом это происходит?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
freezeman
Дата 26.2.2012, 21:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(feodorv @ 26.2.2012,  18:46)
Цитата(freezeman @  26.2.2012,  18:21 Найти цитируемый пост)
т.е. когда я запустил службу 

А каки образом это происходит?

Скомпилировав exe, через командную строку передаю ключ -install
PM MAIL   Вверх
feodorv
Дата 26.2.2012, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(freezeman @  26.2.2012,  21:03 Найти цитируемый пост)
Скомпилировав exe, через командную строку передаю ключ -install 

Как я понимаю, этим сервис лишь прописывается в системе как сервис, но никак не запускается. А сам сервис стартует запуском экзешника без указания опций запуска:
Код

    if (nArgc < 2){
        CServiceHelper serv;            //Создаем объект-помошник для запуска и управления службами
        serv.AddService(L"SServ1",ServiceMain1);//Добавление службы с указанием ее имени
        serv.AddService(L"SServ2",ServiceMain2);//и процедуры ServiceMain
        serv.Start();                    //Вызов StartServiceCtrlDispatcher()
        return 0;                    //Все службы остановлены, выход их программы
    }


То есть:
  • xxx.exe -install   - прописывается в ОС
  • xxx.exe              - стартуем сервис и дожидаемся его завершения
  • xxx.exe -remove - удаляем сервис из системы

Не хватает
  • xxx.exe -stop     - останов сервиса (без удаления)
 smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
xvr
Дата 27.2.2012, 12:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(feodorv @  26.2.2012,  22:14 Найти цитируемый пост)
Как я понимаю, этим сервис лишь прописывается в системе как сервис, но никак не запускается.

Да

Цитата(feodorv @  26.2.2012,  22:14 Найти цитируемый пост)
А сам сервис стартует запуском экзешника без указания опций запуска:

Нет. 'Просто запускать' его должен Service Manager, а не пользователь. Можно из панели управления, либо с коммандной строки через net start SServ1

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


Бывалый
*


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

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



Цитата(xvr @ 27.2.2012,  12:46)
Цитата(feodorv @  26.2.2012,  22:14 Найти цитируемый пост)
Как я понимаю, этим сервис лишь прописывается в системе как сервис, но никак не запускается.

Да

Цитата(feodorv @  26.2.2012,  22:14 Найти цитируемый пост)
А сам сервис стартует запуском экзешника без указания опций запуска:

Нет. 'Просто запускать' его должен Service Manager, а не пользователь. Можно из панели управления, либо с коммандной строки через net start SServ1

Мне нужно создать в службе 3 потока, где их запускать в ServiceMain?
PM MAIL   Вверх
feodorv
Дата 27.2.2012, 13:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

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



Цитата(xvr @  27.2.2012,  12:46 Найти цитируемый пост)
Нет. 'Просто запускать' его должен Service Manager, а не пользователь.

Мда, точно, в функциональность этого экзешника не входит старт/стоп сервиса...

Цитата(freezeman @  27.2.2012,  12:53 Найти цитируемый пост)
Мне нужно создать в службе 3 потока, где их запускать в ServiceMain? 

Зависит от задачи. Если это три сервиса, то на каждый нужен свой ServiceMain:
Цитата(feodorv @  26.2.2012,  22:14 Найти цитируемый пост)
       serv.AddService(L"SServ1",ServiceMain1);//Добавление службы с указанием ее имени
        serv.AddService(L"SServ2",ServiceMain2);//и процедуры ServiceMain

Если это один сервис, но с тремя потоками, тогда одна процедура ServiceMain и запуск потоков из ServiceMain после RegisterServiceCtrlHandlerEx.

Добавлено через 11 минут и 54 секунды
Только надо учесть, что один поток у Вас уже есть)))


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
xvr
Дата 27.2.2012, 13:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(freezeman @  26.2.2012,  18:21 Найти цитируемый пост)
Я решил взять пример здесь, все прекрасно описывается.

Угу, вот только 'минимальным' я бы его не назвал  smile 

Цитата(freezeman @  27.2.2012,  12:53 Найти цитируемый пост)
Мне нужно создать в службе 3 потока, где их запускать

В вашей библиотеке - в наследнике CServiceContext в методе OnServiceStart() (и не забыть их завершить в методе OnServiceStop() )

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


Бывалый
*


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

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



Цитата(xvr @ 27.2.2012,  13:42)
Цитата(freezeman @  26.2.2012,  18:21 Найти цитируемый пост)
Я решил взять пример здесь, все прекрасно описывается.

Угу, вот только 'минимальным' я бы его не назвал  smile 

Цитата(freezeman @  27.2.2012,  12:53 Найти цитируемый пост)
Мне нужно создать в службе 3 потока, где их запускать

В вашей библиотеке - в наследнике CServiceContext в методе OnServiceStart() (и не забыть их завершить в методе OnServiceStop() )

Да, минимальными их назвать трудно))

Я вписывал туда код записи в файл для проверки, но ничего не происходит...Может из-за того, что я сервис стартовал из Диспетчера служб Windows... 
Я ещё подумал, может сделать службу на C# и из нее запускать exe, где запускаются все 3 потока???
PM MAIL   Вверх
xvr
Дата 27.2.2012, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(freezeman @  27.2.2012,  14:52 Найти цитируемый пост)
Я вписывал туда код записи в файл для проверки, но ничего не происходит...

Вставьте запуск нитей непосредственно в ServiceMain перед последним вызовом.

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.0618 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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