10.5: Use launchd to restart crashed apps

Dec 23, '07 10:30:02AM

Contributed by: macavenger

launchd in 10.5 introduces a couple of new flags to the launchd config plists, specifically KeepAlive (bool or dict) and SuccessfulExit (bool, as child of KeepAlive dict). Using these flags, you can tell launchd to launch an application and automatically restart it if it crashes, but NOT if it exits cleanly. This previous hint showed a somewhat different approach to accomplish the same thing.

Using my company's flight management software as an example, you would end up with the following LaunchAgent .plist file, which I put in my home Library/LaunchAgents folder:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>KeepAlive</key>
	<dict>
		<key>SuccessfulExit</key>
		<false/>
	</dict>
	<key>Label</key>
	<string>com.frontierflying.flightmaster</string>
	<key>ProgramArguments</key>
	<array>
		<string>/Users/Shared/FlightMasterStandalone/FlightMaster2004.app/Contents/MacOS/EXE</string>
	</array>
</dict>
</plist>
I made the inital file using Lingon, and then edited it using Propertylist editor to add the KeepAlive dict/SuccessfulExit key set. The program arguments string needs to be the path to the actual executable inside the app bundle, not just to the .app (assuming it is a bundle app) as shown.

Of course, this loads immediately at login. If this is the desired behavior, then you are done. If you don't want this, then put the .plist file in your documents directory or something, and use something like the following two-line script to load it as desired:

launchctl unload /path/to/launchagent.plist
launchctl load /path/to/launchagent.plst
The unload command is needed only if you want to launch the application multiple times in a session. From what I can tell, once loaded, the LaunchAgent remains loaded, and simply stops monitoring the app after it quits cleanly -- but doesn't unload.

In order to relaunch the app, you first have to unload the LaunchAgent, the load it again, thus the first line of the script. That script should be able to be put into an AppleScript using the do shell script AppleScript command if you want (although I didn't test this), or just leave it as a Terminal script. Then just run that script, and launchd will launch your application, monitor it, and restart it if it crashes, but not if it exits cleanly.

Comments (3)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20071220095645567