There are quite a few hints about how to keep programs alive, and restart them when they crash:
They all have one restriction in common, though: They all need to be run before the to-be-monitored program.
In my case, though, I have a faceless background app that has to decide on its own whether it wants to be restarted in case it crashes. So, my app would be launched first and cannot be quit to become a child of a monitoring process (for explanation see below).
I've tried the launchd
solution by writing a plist file like this:
<?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.mydomain.myapp.restartAfterCrash</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/MyApp.app/Contents/MacOS/MyApp</string>
</array>
</dict>
</plist>
It nearly does what I need, but in order to activate it from my app, by invoking it with launchctl load /path/to/file.plist
, it wants to launch my app once more, so that my originally running app would have to quit to let the new instance run.
However, I cannot pass control to another instance of my app, because it's causing several new problems if the app was launched by double clicking a document the Finder or if it was launched by an AppleScript that wants to communicate further with my app. In those cases, my originally launched app must keep running, and thus the launchd
method is not viable, nor is any other method that requires my app to run a new instance instead.
In short, are there other tested (reliable) methods that a Mac application can use to have itself restarted only if it crashes?
The only method I can think of is launching another faceless background application that monitors the first program's lifetime, e.g. via its PID.
I also wonder if it can be done with a simple shell command invocation that would periodically check whether my app is still alive, as those always run as a child process and would die along with the primary app, won't they?