AppleScript: Check if “System Events” has loaded

applescript

When an Active Directory (AD) user logs in, my AppleScript fires and attempts to put their AD home directory in the sidebar for easier access when opening and saving documents.

It works great, but about 10% of the time it fails because "System Events" hasn't loaded. I've tried adding delays using:

do shell script "sleep 2"

But that doesn't solve the problem. I've put the delay up to four seconds, and although it helps, it's certainly not ideal.

It would be a lot easier if I could somehow detect when the "System Events" process has loaded. Does anyone know how to do this within AppleScript?

Best Answer

The System Events process does not start at login, so the delay might be needed for some other reason. System Events also teriminates automatically if it is not used for a few minutes.

It probably won't help, but you could try launching System Events at the start of the script:

launch application "System Events"

You could also try using a launchd agent like this to launch a System Events process at login:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC -//Apple Computer//DTD PLIST 1.0//EN http://www.apple.com/DTDs/PropertyList-1.0.dtd>
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>test</string>
  <key>Program</key>
  <string>/System/Library/CoreServices/System Events.app/Contents/MacOS/System Events</string>
  <key>RunAtLoad</key> <!-- run at login -->
  <true/>
  <key>KeepAlive</key> <!-- run the program again if the previous program terminates -->
  <true/>
</dict>
</plist>

You can normally use something like tell application "System Events" to exists process "Finder" to check if a process exists, but it obviously requires talking to System Events. In this case you might also use a shell script like this:

repeat 100 times
    do shell script "ps -eco comm= | grep -x 'System Events'; exit 0"
    if result is not "" then exit repeat
    delay 0.1
end repeat

ps -e is identical to -ax (include processes from all users and processes without a controlling terminals), -c prints command names instead of absolute paths in OS X, and -o comm= prints only command names without the header row. You can replace the shell command with pgrep -x 'System Events'; exit 0 in 10.8 and later.