Automator "Quit Application" Action stops
Solution 1:
You can try these three potential solutions to see if either fare any better than the built-in Automator action.
The first is a plain AppleScript handler that takes a list of exceptions (apps that are exempt from being quit), and then proceeds to send a quit command to all the others (they being any application process not belonging to a file in the /System
directory--therefore, Finder and System Events will be spared, but Automator will not unless it is specified in the list of exceptions, X
):
to quitAll(X as list)
local X
tell application id "com.apple.SystemEvents" to script Apps
property list : the bundle identifier of processes ¬
where the POSIX path of its application file ¬
does not start with "/System"
property locked : X
end script
tell Apps to repeat with id in its list
ignoring application responses
set A to the application id id
if A's name is not in locked ¬
then try
quit A
end try
end ignoring
end repeat
end quitAll
The second uses the same method as above to retrieve a list of running applications but it grabs their pid
numbers. These are passed en masse to a do shell script
call to kill
the applications (some people get nervous about this, possibly because the name of the command sounds like it's a bad action to perform, but it's perfectly safe, and very standard. Applications typically also save their window and document states, so the kill
command can allow them to retrieve the .savedState
data when re-opened later.
to kill(X as list)
local X
tell application id "com.apple.SystemEvents" to script Apps
property parent : a reference to every process where the ¬
POSIX path of its application file doesn't start with ¬
"/System"
property id : my unix id
property name : my short name
property locked : X
end script
tell Apps to repeat with i from 1 to length of id
if name's item i is in locked ¬
then set id's item i to []
end repeat
set my text item delimiters to space
"kill " & integers in the id of Apps
do shell script result
end kill
The last solution is an AppleScript-ObjectiveC handler that, once again, obtains a list of the running applications that aren't located anywhere in the /System
folder, and don't appear (by name) in the list that's passed to the handler:
to terminate(X as list)
set pred to "!bundleURL.path LIKE '/System/*'" & ¬
"&&!localizedName IN[c] %@"
script
use framework "Foundation"
set [A, P] to a reference to my [¬
NSWorkspace's sharedWorkspace's runningApplications, ¬
NSPredicate's predicateWithFormat_(pred, X)]
(A's filteredArrayUsingPredicate:P)'s terminate
end script
run result
end terminate
I haven't tested this handler to see what permissions need granting, as I didn't want all of my programs to terminate. But let me know if there are any hiccups and I'll direct you accordingly. The word terminate
inside the handler can be replaced by forceTerminate
(case sensitive) to do a force quit on each application instead. This, if it were me, would actually be my preference, as I have set my system to save the state of applications on forced terminations, and it avoids the "Do you want to save the current document?" banality.