Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Обработка искл. ситуаций в WinNT Service [D7, WinXP]


Страницы:   1 2

Прогер ©   (2006-12-22 08:30:00) 

Глобальная переменная TApplication для EXE предусматривает обработчик (событие) OnException, с помощью которого я протоколирую все возникающие исключительные ситуации. Но это в приложении (EXE). А как быть с сервисом?


Прогер   (2006-12-22 11:45:00) [21]


> А это не твой сервис такое исключение выдал.

Боюсь, что мой. Только вот почему?

Раньше писал сервисы на Win2000, работало. Сейчас (первый раз) для WinXP. Создал "пустой" сервис - та же ошибка в системном журнале. В чём дело, понять не могу.


Сергей М.   (2006-12-22 11:38:00) [22]

А это не твой сервис такое исключение выдал. До его запуска дело вообще не дошло, судя по тексту в записи.


Прогер   (2006-12-22 11:34:00) [23]


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


В журнале такая вот запись. Как так?

Сбой при запуске службы "имя" из-за ошибки: "имя" не является приложением Win32.


oxffff   (2006-12-22 11:02:00) [24]


> Прогер   (22.12.06 10:40) [11]
>
> > бработчик приведенный [2] сработает только тогда сервис
>
> > уже "отвалится".
>
>
> Смысл в том, чтобы протоколировать все исключительные ситуации,
>  у которых нет "локального" try...except.


Так если нет локального "try...except".
управление выйдет за RUN, а перед еще и вызовет StartThread.Free;
Ты только запротоколируешь "падение сервиса".


Сергей М.   (2006-12-22 10:51:00) [25]


> Прогер   (22.12.06 10:40) [11]


Что значит "проконтролировать" ?
Если просто вести протокол, так он и так уже ведется объектом Application, без необходимости твоего явного вмешательства. Инф-ция о необработанных исключениях исправно записывается в системный лог, там ты все это и увидишь.


Прогер   (2006-12-22 10:40:00) [26]


> бработчик приведенный [2] сработает только тогда сервис
> уже "отвалится".


Смысл в том, чтобы протоколировать все исключительные ситуации, у которых нет "локального" try...except.


Сергей М.   (2006-12-22 10:02:00) [27]


> Прогер   (22.12.06 08:54) [2]


Могу предложить "извращенный" способ глобальногоперехвата искл-й в сервис-процессе, хотя ты вряд ли его потянешь.

Суть метода заключается в перехвате либо вызова метода TEventLogger.LohMessage либо непосредственно WinAPI-ф-ции ReportEvent()

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


oxffff   (2006-12-22 09:55:00) [28]


> Сергей М. ©   (22.12.06 09:42) [6]
>
> > oxffff ©   (22.12.06 09:27) [4]
>
>
> Это из другой оперы.
>
> А текущая опера - это TServiceApplication, и реализация
> метода Run у него, мягко говоря, иная, хотя концептуально
> не отличается - организован тот же цикл ожидания/выборки/диспетчеризации
> сообщений.


Благодарю за поправку.


  try
    while not Forms.Application.Terminated do
      Forms.Application.HandleMessage;
    Forms.Application.Terminate;
    if StartThread.ReturnValue <> 0 then
      FEventLogger.LogMessage(SysErrorMessage(StartThread.ReturnValue));
  finally
    StartThread.Free;
  end;


Обработчик приведенный [2] сработает только тогда сервис уже "отвалится".


> Сергей М. ©   (22.12.06 09:45) [8]
>
> > где её скачать?
>
>
> Кажись, на сайте у Анатолия Подгорецкого (С) она есть.


GOOGLE
программирование серверных приложений djvu


Сергей М.   (2006-12-22 09:45:00) [29]


> где её скачать?


Кажись, на сайте у Анатолия Подгорецкого (С) она есть.


Прогер   (2006-12-22 09:43:00) [30]


procedure TServiceApplication.Run;

 function FindSwitch(const Switch: string): Boolean;
 begin
   Result := FindCmdLineSwitch(Switch, ['-', '/'], True);
 end;

var
 ServiceStartTable: TServiceTableEntryArray;
 ServiceCount, i, J: Integer;
 StartThread: TServiceStartThread;
begin
 AddExitProc(DoneServiceApplication);
 if FindSwitch('INSTALL') then
   RegisterServices(True, FindSwitch('SILENT'))
 else if FindSwitch('UNINSTALL') then
   RegisterServices(False, FindSwitch('SILENT'))
 else
 begin
   Forms.Application.OnException := OnExceptionHandler;
   ServiceCount := 0;
   for i := 0 to ComponentCount - 1 do
     if Components[i] is TService then Inc(ServiceCount);
   SetLength(ServiceStartTable, ServiceCount + 1);
   FillChar(ServiceStartTable[0], SizeOf(TServiceTableEntry) * (ServiceCount + 1), 0);
   J := 0;
   for i := 0 to ComponentCount - 1 do
     if Components[i] is TService then
     begin
       ServiceStartTable[J].lpServiceName := PChar(Components[i].Name);
       ServiceStartTable[J].lpServiceProc := @ServiceMain;
       Inc(J);
     end;
   StartThread := TServiceStartThread.Create(ServiceStartTable);
   try
     while not Forms.Application.Terminated do
       Forms.Application.HandleMessage;
     Forms.Application.Terminate;
     if StartThread.ReturnValue <> 0 then
       FEventLogger.LogMessage(SysErrorMessage(StartThread.ReturnValue));
   finally
     StartThread.Free;
   end;
 end;
end;



> А вообще батенька открой синенькую книжку Рихтера.

Быть может, добрые люди подскажут мне, где её скачать? Спасибо.


Сергей М.   (2006-12-22 09:42:00) [31]


> oxffff ©   (22.12.06 09:27) [4]


Это из другой оперы.

А текущая опера - это T ServiceApplication, и реализация метода Run у него, мягко говоря, иная, хотя концептуально не отличается - организован тот же цикл ожидания/выборки/диспетчеризации сообщений.


oxffff   (2006-12-22 09:31:00) [32]

А вообще батенька открой синенькую книжку Рихтера.
И читай до посинения.


oxffff   (2006-12-22 09:27:00) [33]


>Прогер   (22.12.06 08:54) [2]
> Да муторно, знаете ли, батенька... :)
>
> Можно, конечно, и так:


А разве батенька так можно?

Ты посмотри реализацию RUN

procedure TApplication.Run;
begin
 FRunning := True;
 try
   AddExitProc(DoneApplication);
   if FMainForm <> nil then
   begin
     case CmdShow of
       SW_SHOWMINNOACTIVE: FMainForm.FWindowState := wsMinimized;
       SW_SHOWMAXIMIZED: MainForm.WindowState := wsMaximized;
     end;
     if FShowMainForm then
       if FMainForm.FWindowState = wsMinimized then
         Minimize else
         FMainForm.Visible := True;

     repeat
       try
         HandleMessage;
       except
         HandleException(Self);
       end;
     until Terminated;

   end;
 finally
   FRunning := False;
 end;
end;

До твоего супер обработчика дойдет только, если HandleException создаст
исключение.

А для 99.99999% случаев твой вариант батенька ошибочный.


Сергей М.   (2006-12-22 09:08:00) [34]


> муторно, знаете ли, батенька


А сервисы, уважаемый, вообще муторная штука)

Здесь надо понимать, что обработчики основных сервисных событий OnStart/Stop/Execute выполняются в контекстах соответствующих доп.потоков.
Одно и то же сервис-приложение может создать более чем один сервис-объект, и каждый из этих объектов создаст свой доп.поток, в котором соотв.сервис и будет "крутиться по хозяйству". Эти доп.потоки независимы друг от друга, обработка исключений в каждом из них возлагается на сам поток.
Тот код, что ты привел в [2], будет обрабатывать искл-я, возникающие лишь в основномпотоке процесса сервис-приложения.


Прогер   (2006-12-22 08:54:00) [35]

Да муторно, знаете ли, батенька... :)

Можно, конечно, и так:


program proDgstSenderService;

uses
 SvcMgr,
 uSender in 'uSender.pas' {srvcSender: TService},
 uProc in '..\..\_Gnrl\uProc.pas',
 uFuncDgstSender in '..\uFuncDgstSender.pas',
 uConst in '..\uConst.pas',
 uRAR in '..\..\_Gnrl\uRAR.pas';

{$R *.RES}

begin
try
 Application.Initialize;
 Application.CreateForm(TsrvcSender, srvcSender);
 Application.Run;
except
... // протоколирование в файл
end
end.


Однако, может кто подскажешь более эстетичное решение?


Сергей М.   (2006-12-22 08:50:00) [36]

А оч просто.

Тела всех назначенных тобой обработчиков событий заключай в try..except


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо