开发者

try/except doesn't seem to capture exceptions - Delphi Service Application

I have a service written in Delphi 2007 in which I'm trying capture any unknown exceptions. Assigning a method to the on exception doesn't seem to work ('Forms.Application.OnException:=UnknownApplicationException'). The 'UnknownApplicationException' doesn't appear to get called - I attribute this to the fact that there is no form in the application so the method never actually gets assigned. Aside from this, I've also tried creating an exception on a timer (after commenting out 'Forms.Application.OnException:=UnknownApplicationException' so that it does not interfere). The timer triggers 60 seconds after the service has started up:

procedure TProcessScheduler.Timer1Timer(Sender: TObject);    
begin    
  try    
    Raise Exception.Create('THIS GIG SUCKS');    
  except     
    LogEvent(Name,rsUNKNOWN_EXCEPTION,EVENTLOG_AUDIT_FAILURE,0);    
    ExitCode:=-1;    
    Halt;    
  end;     
end;

The exception never seems to g开发者_开发问答et captured - the service starts up and after 60 seconds when this timer triggers, I hear a windows error sound but don't see any error dialog - perhaps this could be due to the fact that the application is a service? The 'Halt' never gets called and the application keeps running (i assume its waiting for someone to click ok on the invisible error dialog that it created). Any ideas why the code under the 'except' doesn't get called? Thanks in advance! KP


Reassigning Forms.Application.OnException is a bad idea, as TServiceApplication.Run() does this itself. You either do it before, then your assignment won't have an effect, or you do it afterwards, in which case you remove the exception handling mechanism that has been put into place.

If you leave the handling in place, then all exceptions will be logged to the Windows Event Logger, which seems a reasonable thing to do from a service.


A couple of notes:

  • As you are raising an exception within a try-except block, it should not trigger any Application.OnException handler, simply because the exception isn't unhandled.

  • How have you determined that the Halt doesn't get called? Does the exception get logged through your LogEvent?

  • In a Service application ExitCode and Halt don't function the way you would expect them to in a normal windows application. A service isn't stopped by calling halt, it should be stopped by going through the Windows' Service Control Manager.

  • If the except part of your try-except block is indeed not reached, it means that Windows has cut in because something has happened that it isn't happy with. That could be something in the LogEvent method you are calling. If that shows a dialog or if that raises an exception as well, the ExitCode and Halt won't be reached.

  • A service doesn't normally have a desktop associated with it, so showing dialogs isn't going to work.

  • If you need the service to show dialogs (bad idea by the way, services are intended to run without user interaction), you need to make it interactive and have it run under another user account than the normal "system" account that services run under. You do this through the services manager.


Why are you setting Forms.Application? AFAIK a service uses the Application variable declared in SvcMgr, which is declared as:

var
  Application: TServiceApplication = nil;

Moreover a service should not display any dialog, it may not have access to the user desktop, and your dialog will hang the service. There are ways to display a dialog anyway, but services could also run when no human user is watching the screen. Log events to the event log (or if you don't like it to a file, but the event log has several useful features, including remote access).


I create my own version of the SvcMgr.pas file to eliminate the in-place hook to the Application global exception handler so that I can instantiate my own. I do this because 1) I could find no other simple way of doing this, and 2) since this unit is a stand-alone unit that is only included with Windows Services then the effect on other units is minimal. You can download the code from my web-site to see how this works.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜