AppleScript Tips: Inspecting Objects, Modal Dialogs, and More
Tags: applescript, macos • Categories: Software
AppleScript is an amazing, quirky tool within the macOS ecosystem. It enables you to control any application on your Mac, even if the original developer didn’t explicitly write an API for it. This can be incredibly useful when attempting to automate certain actions. However, the language is incredibly weird and confusing, especially to a "real" software developer. I’ve compiled a list of tips and tricks below that help me write various tools and scripts to automate my computer (I’ve written about applescript before in case you are looking for other tricks).
Get Process Reference by Application Path
Here’s how to get all of the process paths currently running:
tell application "System Events"
set processList to get the POSIX path of application file of every process
end tell
And here’s how to get a particular process reference based on an input path and use it with "System Events"
tell application "System Events"
set processID to (id of 1st process whose POSIX path of application file is appPath)
tell process id processID
UI elements
end tell
end tell
Note that id
is used and not unix id
. id
is a non-standard applescript id that can be used with tell process
.
Retrieve All UI Elements
UI elements
is a special command that can be used to retrieve all elements of a process:
tell application "System Events"
tell process "Finder"
UI Elements
end tell
end tell
You can also get UI elements of a particular UI element:
tell application "System Events"
tell process "Finder"
UI Elements of window 1
end tell
end tell
This can be particularly helpful when combined with the "Accessibility inspector" application.
Inspecting Properties of an Object
tell application "System Events"
return properties of service "Test VPN" of network preferences
end tell
Getting a List of Running Processes
tell application "System Events"
return processes
end tell
Targeting Modals
Depending exactly on how the application is architected, modals are generally represented as a sheet in AppleScript lingo. This means to target the button within the modal, you need to retrieve the sheet and then target the button within that sheet. Here’s an example:
tell application "System Events"
tell process "App Name"
set frontmost to true
click button "Yes" of sheet 1 of window i
end tell
end tell
end tell
Note that in the application inspector, an alert dialog is represented as an alert. It’s only when attempting to target a button within the alert via system events that you must use the sheet terminology.
Check if Application is Running
Helpful for returning early if the application is not running that you are trying to manipulate (credit).
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
if is_running("Finder") is false then return
Closing an Application’s Modal Dialog Window
This involves simulating the pressing of the escape key on the dialog window.
tell application "System Events"
tell process "Process Name"
set frontmost to true
-- escape key
key code 53
end tell
end tell
POSIX Path of Home Folder
POSIX path of (path to home folder) as string
Example: Automatically Logging Out of Twitter
Here’s an example of the type of scripts that I’ll whip up using these tricks. I don’t enjoy most social media, but I really enjoy Twitter. It’s such a fun place to find new ideas and run into interesting people. However, I try to control my usage as much as I can, which means I attempt to block Twitter and log out of it at the beginning of each day.
Here’s a script I use to automatically log out of Twitter when my computer starts up (here’s the full script):
tell application "Safari"
log "Opening Twitter"
activate
open location "https://twitter.com/logout"
end tell
tell application "System Events"
tell process "Safari"
delay 2
log "Attempting to log out"
click button "Log out" of group 1 of group 1 of group 1 of UI element 1 of scroll area 1 of group 1 of group 1 of tab group 1 of splitter group 1 of window 1
delay 1
end tell
end tell
tell application "Safari"
log "Closing twitter page"
close current tab of front window
end tell
Example: Automatically Quitting LinkedIn Helper
LinkedIn helper is a really interesting automation tool for LinkedIn. It’s very hacky, so you want to make sure it’s not running except when you intend to be using it. Here’s a script I wrote to make sure it’s quit every morning:
on quitLinkedHelper()
try
tell application "linked-helper" to quit
on error errMsg
log "Error quitting linked-helper: " & errMsg
end try
end quitLinkedHelper
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
if is_running("linked-helper") is false then return
quitLinkedHelper()
delay 2
set appPath to "/Applications/linked-helper.app"
set subAppPath to "/Applications/linked-helper.app/Contents/Resources/out/linked-helper.app"
tell application "System Events"
set processID to (id of the first process whose POSIX path of application file is subAppPath)
tell process id processID
set frontmost to true
repeat with i from 1 to 4
try
-- Attempt to click the "Yes" button on sheet 1 of each window, which one the modal is on changes each time
click button "Yes" of sheet 1 of window i
-- Exit the loop if the click succeeds
exit repeat
on error errMsg
-- Log the error and continue to the next window
log "Error clicking on window " & i & ": " & errMsg
end try
end repeat
end tell
end tell
delay 5
quitLinkedHelper()