Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.09.03;
Скачать: CL | DM;

Вниз

Проблемы с сервисом   Найти похожие ветки 

 
ПЛОВ ©   (2006-08-07 16:13) [0]

Написал болванку сервиса с использованием предоставленных мне примеров и информации из MSDN. Вроде все правильно. Сервис устанавливаеться и удаляеться без проблем. Но упорно не желает запускаться. StartServiceCtrlDispatcherA выдает ошибку. Подозреваю что для "минимального сервсиса" чего-то не хватает но не могу понять чего...

const PCHAR ServName = "test";
const PCHAR ServDispName = "test";

CHAR szPath[MAX_PATH];
SC_HANDLE schSCManager;
SC_HANDLE schService;

SERVICE_STATUS srvStat;
SERVICE_STATUS_HANDLE srvStatHandle;
//-----------------------------------------------------
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
...
SERVICE_TABLE_ENTRYA DispatchTable[] =
{
{ServName, (LPSERVICE_MAIN_FUNCTIONA)ServiceProcA},
{NULL, NULL}
};
//запуск
if (!StartServiceCtrlDispatcherA(DispatchTable)) // тут ошибка
WriteError("StartServiceCtrlDispatcherA failed", GetLastError()); // - возвращает 1063
return 0;
}

остальное имеет такой вид (практически полностью взято из MSDN)

// Stub initialization function.
DWORD ServiceInitializationA(DWORD argc, PCHAR * argv, DWORD * specificError)
{
argv;
argc;
specificError;
return(0);
}

void WINAPI ServiceCtrlHandler(DWORD Opcode)
{
DWORD status;
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
// Do whatever it takes to pause here.
srvStat.dwCurrentState = SERVICE_PAUSED;
break;

case SERVICE_CONTROL_CONTINUE:
// Do whatever it takes to continue here.
srvStat.dwCurrentState = SERVICE_RUNNING;
break;

case SERVICE_CONTROL_STOP:
// Do whatever it takes to stop here.
srvStat.dwWin32ExitCode = 0;
srvStat.dwCurrentState = SERVICE_STOPPED;
srvStat.dwCheckPoint = 0;
srvStat.dwWaitHint = 0;

if (!SetServiceStatus(srvStatHandle, &srvStat))
{
status = GetLastError();
WriteError("SetServiceStatus failed", status);
}
WriteLog("Leaving Service");
return;

case SERVICE_CONTROL_INTERROGATE:
// Fall through to send current status.
break;

default:
WriteError("Unrecognized opcode", Opcode);
}

// Send current status.
if (!SetServiceStatus (srvStatHandle, &srvStat))
{
status = GetLastError();
WriteError("SetServiceStatus failed", status);
}
return;
}
//---------------------------------------------------------------------------------------
void WINAPI ServiceProcA(DWORD argc, LPSTR * argv)
{
DWORD status;
DWORD specificError;

srvStat.dwServiceType = SERVICE_WIN32;
srvStat.dwCurrentState = SERVICE_START_PENDING;
srvStat.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
srvStat.dwWin32ExitCode = 0;
srvStat.dwServiceSpecificExitCode = 0;
srvStat.dwCheckPoint = 0;
srvStat.dwWaitHint = 0;

srvStatHandle = RegisterServiceCtrlHandlerA(ServName, ServiceCtrlHandler);
if (srvStatHandle == (SERVICE_STATUS_HANDLE)0)
{
WriteError("RegisterServiceCtrlHandlerA failed", GetLastError());
return;
}

status = ServiceInitializationA(argc, argv, &specificError);
// Handle error condition
if (status != NO_ERROR)
{
srvStat.dwCurrentState = SERVICE_STOPPED;
srvStat.dwCheckPoint = 0;
srvStat.dwWaitHint = 0;
srvStat.dwWin32ExitCode = status;
srvStat.dwServiceSpecificExitCode = specificError;

SetServiceStatus(srvStatHandle, &srvStat);
return;
}
// Initialization complete - report running status.
srvStat.dwCurrentState = SERVICE_RUNNING;
srvStat.dwCheckPoint = 0;
srvStat.dwWaitHint = 0;

if (!SetServiceStatus(srvStatHandle, &srvStat))
{
status = GetLastError();
WriteError("SetServiceStatus failed", status);
}

// This is where the service does its work.
WriteLog("!типа сработало!");

return;
}


 
isasa ©   (2006-08-07 16:32) [1]

А если вот так, как в примерах? :)

  SERVICE_TABLE_ENTRY   dispTable[] = {
     { (LPTSTR)ServName, ServiceProcA},
     { NULL, NULL}
  };
  if (!StartServiceCtrlDispatcher((LPSERVICE_TABLE_ENTRY)&dispTable[0]))
  ...


Кроме этого, фигня какая то.

const PCHAR ServName = "test";
const PCHAR ServDispName = "test";

Надо бы так. С юникодом(жирным).

const TCHAR ServName = _T("test");
const TCHAR ServDispName = _T("test");


 
isasa ©   (2006-08-07 16:35) [2]

Да и еще, "главная" - желательно простое консольное приложение
не
int APIENTRY _tWinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)

а
int _tmain(int argc, _TCHAR* argv[])


 
ПЛОВ ©   (2006-08-07 16:38) [3]

Не может же быть ошибочной вся функция StartServiceCtrlDispatcherA? Я уже все остальное написал именно под А, так сказать, переписать конечно можно, но и это должно работать :(


 
ПЛОВ ©   (2006-08-07 16:42) [4]

Неужели сервис может работать только с юникодом и только в консольном приложении?


 
isasa ©   (2006-08-07 16:46) [5]

А при чем здесь А, W ...
ServiceProcA,  ServiceCtrlHandler - это просто твои имена твоих точек входа, называй как хочешь. Имя сервиса в юникоде.
Хотя здесь неправилино заполнена dispTable.


 
ПЛОВ ©   (2006-08-07 16:54) [6]


> Хотя здесь неправилино заполнена dispTable.

Неправильно в плане НЕиспользования юникода? Но ведь есть же SERVICE_TABLE_ENTRYA, StartServiceCtrlDispatcherA значит эти функции должны работать с Анси-строками...


 
isasa ©   (2006-08-07 17:02) [7]

Меня глежет смутные сомнения, как запускаем то?


 
ПЛОВ ©   (2006-08-07 17:14) [8]


> Меня глежет смутные сомнения, как запускаем то?

Через панель управления стандартно.

Только что переустановил сервис и он стал запускаться (мистика :) ) Но как бы формально, потому что эта строка не выполняеться:
   // This is where the service does its work.
   WriteLog("!типа сработало!");

Хотя возможно и не должна...


 
ПЛОВ ©   (2006-08-07 17:27) [9]

И еще такой вопрос, как я понимаю, события, указанные в ServiceCtrlHandler вроде SERVICE_CONTROL_PAUSE вызываються тогда, когда с севисом производиться указанное действие, правильно? Я добавил туда запись всех этих действий в лог-файл. Ничего не пишеться.


 
isasa ©   (2006-08-07 17:29) [10]

Ну, слава Богу. Для приличия можно добавить уведомление о завершении ...

// This is where the service does its work.
WriteLog("!типа сработало!");
//
srvStat.dwCurrentState = SERVICE_STOPPED;
srvStat.dwCheckPoint = 0;
srvStat.dwWaitHint = 0;
srvStat.dwWin32ExitCode = status;
srvStat.dwServiceSpecificExitCode = specificError;

SetServiceStatus(srvStatHandle, &srvStat);


 
isasa ©   (2006-08-07 17:37) [11]

ПЛОВ ©   (07.08.06 17:27) [9]
Куда, туда? :)
SERVICE_CONTROL_PAUSE и иже, это только уведемления о том, что надо тормозить. Тормозить должен сам(руками или чем придется). Посмотри примеры на основе потока. Очень удобно. Тормозишь и посылаешь уведомление
....
case SERVICE_CONTROL_PAUSE:
   srvStat.dwCurrentState = SERVICE_PAUSED;
   SuspendThread(mhThread);
...
case SERVICE_CONTROL_CONTINUE:
   srvStat.dwCurrentState = SERVICE_RUNNING;
   ResumeThread(mhThread);
...
if (!SetServiceStatus (srvStatHandle,  &srvStat)) ...


 
ПЛОВ ©   (2006-08-07 17:37) [12]


> Ну, слава Богу. Для приличия можно добавить уведомление
> о завершении ...

Добавил... Вроде код работает, сервис запускаеться и сразу-же выдаеться сообщение о его остановке (оно?), но лог не ведеться!


 
Ketmar ©   (2006-08-07 17:48) [13]

оффтоп.
> [11] isasa ©   (07.08.06 17:37)
> Тормозить должен сам(руками или чем придется).
долго плакал. tnx. %-)


 
isasa ©   (2006-08-07 17:48) [14]

Естественно не выдаст, если ты иеешь ввиду "Leaving Service", т.к. оно стоит после уведомления о завершении. А ты переставо до...

case SERVICE_CONTROL_STOP:
// Do whatever it takes to stop here.
srvStat.dwWin32ExitCode = 0;
srvStat.dwCurrentState = SERVICE_STOPPED;
srvStat.dwCheckPoint = 0;
srvStat.dwWaitHint = 0;

if (!SetServiceStatus(srvStatHandle, &srvStat))
{
status = GetLastError();
WriteError("SetServiceStatus failed", status);
}
WriteLog("Leaving Service"); //<----


 
isasa ©   (2006-08-07 17:50) [15]

Ketmar ©   (07.08.06 17:48) [13]
Хотел написать тем, что было в инструкции по пользованию шведской бензопилой, но постеснялся ...


 
ПЛОВ ©   (2006-08-07 17:52) [16]

Да, я поставил сразу после каждого case SERVICE_CONTROL_что-то WriteLog
Не пишеться. Вот порыскал и нашел описание своей ошибки:
FAILED_SERVICE_CONTROLLER
Процесс службы не может установить связь с контроллером службы


 
isasa ©   (2006-08-07 18:00) [17]

Добавь фрагмент

if (error) {
   LPVOID lpMsgBuf;
   DWORD dw = GetLastError();
   FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
      NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL );
   wprintf(L"Error message. (0x%08X)%s\n", dw, lpMsgBuf);
   LocalFree(lpMsgBuf);
   return ...
}

и не будешь рыскать в поисках текта сообщения о ошибке.
Фрагмент для юникода.
Преобразования вывода на консоль CharToOem.


 
ПЛОВ ©   (2006-08-07 18:03) [18]


> и не будешь рыскать в поисках текта сообщения о ошибке

Главное ее найти и уничтожить :)


 
ПЛОВ ©   (2006-08-07 18:12) [19]

Объясните хоть что она означает? Чтобы знать куда копать...


 
isasa ©   (2006-08-07 18:18) [20]

ПЛОВ ©   (07.08.06 18:12) [19]
Это ты про
isasa ©   (07.08.06 18:00) [17]


 
ПЛОВ ©   (2006-08-07 18:20) [21]


> isasa ©   (07.08.06 18:18) [20]

Я про саму ошибку FAILED_SERVICE_CONTROLLER. Что она означает? Из описания мало что понятно...



Страницы: 1 вся ветка

Текущий архив: 2006.09.03;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.031 c
9-1126905842
rsy
2005-09-17 01:24
2006.09.03
DirectX или OpenGL


6-1144955552
qazwsx
2006-04-13 23:12
2006.09.03
base64_encode(pack("H*", sha1(utf8_encode($_GET[ pwd ])))))


15-1155462612
Батыр
2006-08-13 13:50
2006.09.03
про диск


15-1154954506
antonn
2006-08-07 16:41
2006.09.03
ищу музончик...


15-1155119751
Карелин Артем
2006-08-09 14:35
2006.09.03
Будущее сайта





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский