MacOS – AppleScript: How to get all window names of processes that share the same title

applescriptmacos

The process, RSScriptRunner, represents a currently running script that was triggered by FastScripts.app. (FastScripts does not assign unique process titles to scripts that it triggers.)

If one has multiple processes titled RSScriptRunner running simultaneously, then the following code:

tell application "System Events" to windows of process "RSScriptRunner"

will only return the window name of the process that began the earliest.

However, I would like to get every window name of every RSScriptRunner process.

Does anyone know how to accomplish this in AppleScript?


My ultimate intent here is to implement a check that ensures that only one instance of one script can run simultaneously. Multiple different scripts running is okay, but multiples of a script running at the same time is undesirable.

The code would look something like this:

tell application "System Events"
    set theWindowList to windows of process "RSScriptRunner"
    if theWindowList contains "The title of the initial dialog of this script goes here." then
        error number -128
    end if
end tell

This check would be located at the very top of the script.


Note:

This is very much a situation where minimal latency is crucial.

I had devised a long-winded method that successfully realized my desired outcome. The method entailed getting every current process title into one list, and getting every current process ID into another, corresponding list. I then retrieved the window name of each RSScriptRunner process via its respective process ID (which, unlike the process name, must be unique).

However, this method brought with it a couple seconds of latency. I need a solution that is nearly instant (such as, the line of code above).

Best Answer

Note: On my system, macOS Sierra, there is no window for this process.

You can use a whose clause, like this:

For a process that contains only one window, use this script:

tell application "System Events"
    set theWindowList to name of window 1 of (processes whose name is "RSScriptRunner")
    if theWindowList contains "The title of the initial dialog of this script goes here." then
        error number -128
    end if
end tell

For a process that can contain one or more windows, use this script:

tell application "System Events"
    set myList to name of windows of (processes whose name is "RSScriptRunner") -- get a list of lists, each sublist contains names 
end tell
set theWindowList to my subListsToOneList(myList) --  Flattening a list of lists

if theWindowList contains "The title of the initial dialog of this script goes here." then
    error number -128
end if

on subListsToOneList(l)
    set newL to {}
    repeat with i in l
        set newL to newL & i
    end repeat
    return newL
end subListsToOneList

The solution for macOS Sierra, maybe it works for other OSes as well, to get the name of the launched scripts, is to use the ps and pgrep commands.

set theNameList to paragraphs of (do shell script "ps -p $(pgrep -x RSScriptRunner) | sed -n 's:.*RSScriptRunner.*/::p'") -- get the name of the scripts
if theNameList contains "the name of this script.scpt" then error number -128

Informations:

  • $(pgrep -x RSScriptRunner) : A sub shell to get the process ID of each instance of the RSScriptRunner, the '-x' option: require an exact match of the process name
  • ps -p: get the command of each PID (the result contains the path of the launched script).
  • The sed command : delete characters from the beginning of the line through the last slash character to get the name of the script (the -noption is to print the line which contains the 'RSScriptRunner' word only, because the first line is the headers --> PID TTY TIME CMD).