Fog Creek Software
Discussion Board




Howto:"Fallover" recovery for Windows application?

Here is what I would like to do. I have an ordinary Windows application (not a service) that I am developing (in Delphi 7, FYI.) I would like to have a way to automatically restart this application if it ever crashes. So if the application crashed, the same application would be immediately restarted.

I would basically like behavior similar to the "Recovery" options for Windows 2000 & XP services. (no, I don't want to make this application into an actual service. It needs a user interface. Yeah, I know I can hook a UI to a service. But not, I don't want to get that elaborate.)

The application will only run on an internal server and will not be resold, so a GNU "copyleft" or separate commercial application would be fine.

My guess is that someone somewhere has written a freeware application that allows a specified command line to be registered with it, which it "watchdogs".

Thanks.

Bored Bystander
Wednesday, September 17, 2003

Here's a thought,
Write a Shell application that lauches the one you always want to run.  Execute (ShellExecuteEx) your "main" application and then wait on the process handle (WaitSingleObjectEx) to terminate.  whenever your main app shuts down, re-execute it(Of course this would put you in a perpetual loop, unless you kill the shell application- to get around this create a named event that both applications use.  If the main app shuts down normally, in the shell app check and see if this event is signaled- if so just bail- otherwise restart)

MikeG
Wednesday, September 17, 2003

Writing a monitor application is probably overkill.  You can override the default handler for unhandled exceptions.  The typical causes of crashes (access violations, illegal instructions, etc.) go through this mechanism. 

I'm not a Delphi expert but I believe this can be easily done by providing your own Application.OnException handler and then calling ShellExecute (from the Win32 API) to relaunch your app. 

Something like this:

procedure MainForm.AppExceptionHandler(Sender: TObject; E: Exception);
begin
    { display error message box }
    Application.ShowException(E);

    { launch new instance }
    ShellExecute(0,'','app.exe','','',SW_SHOWNORMAL);

    { terminate this instance }
    Application.Terminate();
end;

SomeBody
Wednesday, September 17, 2003

Somebody - good observations and example. That would solve my design challenge. Mainly I'm concerned about some unanticipated and unhandled exception causing the application to terminate. I would just like to be able to tell my client that if the application dies (over the weekend, say) it will try to run itself again up to N times.

This begs the question - are there any classes of run time errors that the Delphi Application.OnException handler doesn't intercept?

Bored Bystander
Wednesday, September 17, 2003

I'm not so sure that you can rely on having the application terminate itself on unhandled exceptions. There may be cases where the runtime will display a dialog box that requires user intervention before the process terminates.

I would consider writing a small watchdog application to periodically verify that the main application is actually running (processing messages), and if not, kill the process and restart it.

Big B
Wednesday, September 17, 2003

Perhaps have your app have an API that can processes a message like "are you alive". I you don't get an affirmative back within a certain timeout, kill it and restart it.

pdq
Wednesday, September 17, 2003

On windows 2k the supurious dialog thing really isn't a problem.  I've written watchdog apps.  It really isn't difficult.  You can also buy them off the shelf.

christopher baus
Wednesday, September 17, 2003

Yes, you can write a watchdog application. But that might fail, so you have to write a watchdog watchdog that can restart the watchdog. But the watchdog watchdog could fail so....

Clutch Cargo
Wednesday, September 17, 2003

>>
I'm not so sure that you can rely on having the application terminate itself on unhandled exceptions. There may be cases where the runtime will display a dialog box that requires user intervention before the process terminates.
<<

That's exactly what the code I posted is intended to circumvent.  By default, the Delphi runtime calls Application.ShowException to display the dialog box on unhandled exceptions.  By overriding the default handler, you reliably override this behavior with whatever you'd like.

It's a good question about whether or not OnException catches all possible runtime errors.  I don't know the answer to this but I would guess that OnException catches anything covered by Win32 SEH.  In this case, it should catch anything you could possibly recover from (it won't help with a blue screen of death, of course). 

If you want to read about this stuff at the low level, look up Win32 Structured Exception Handling (SEH). 

SomeBody
Wednesday, September 17, 2003

I googled for this, and found some more info on what I was talking about:

"Delphi executables will die with runtime error 217 when an exception was raised before SysUtils is initialized or after it is finalized. In both situations the regular exception handling is not put in place."

http://www.delphifaq.com/fq/q1050.shtml

Big B
Wednesday, September 17, 2003

That would make sense given that SysUtils seems to be where the exception handling stuff is initialized.  If you have a problem before SysUtils initializes, restarting the application isn't going to help.

SomeBody
Thursday, September 18, 2003

Clutch,

I've thought about that problem, but since the watchdog has about 100 lines of code and the application a couple hundred thousand, I have more faith in the watchdog.

christopher baus
Friday, September 19, 2003

*  Recent Topics

*  Fog Creek Home