Here is a simple script to quit all the open apps.
-- Application bundle identifiers can be obtained using osascript -e 'id of app "SomeApp"'
property white_list : {"com.apple.finder"}
tell application "System Events"
set bundleIDs to bundle identifier of processes whose background only is false
end tell
repeat with theID in bundleIDs
if theID is not in white_list then tell application id theID to quit
end repeat
instead of telling the app id to quit, I had it show me an alert so I could see what it was getting.
For some reason I would intermittently get āmsngā as one of the bundle identifiers.
Like soā¦
-- Application bundle identifiers can be obtained using osascript -e 'id of app "SomeApp"'
property white_list : {"com.apple.finder"}
tell application "System Events"
set bundleIDs to bundle identifier of processes whose background only is false
end tell
repeat with theID in bundleIDs
if theID is not in white_list then
--tell application id theID to quit
display alert theID
end if
end repeat
So I added āmsngā to the white_list like soā¦
-- Application bundle identifiers can be obtained using osascript -e 'id of app "SomeApp"'
property white_list : {"com.apple.finder", missing value}
tell application "System Events"
set bundleIDs to bundle identifier of processes whose background only is false
end tell
repeat with theID in bundleIDs
if theID is not in white_list then tell application id theID to quit
end repeat
Just figured out āmsngā is āmissing valueā
Here is the script fixed to avoid this bugā¦
-- Application bundle identifiers can be obtained using osascript -e 'id of app "SomeApp"'
property white_list : {"com.apple.finder"}
local theID, bundleIDs
tell application "System Events"
set bundleIDs to bundle identifier of processes whose background only is false
end tell
repeat with theID in bundleIDs
if class of theID is text then
if theID is not in white_list then tell application id theID to quit
end if
end repeat
Itās a bug.
The line to get the Bundle IDs is creating a list from running processes. I believe the script (running as a compiled app) is itself returning a blank(i.e. missing value) .
So my script above traps for that
** EDIT** i figured it out. You named the script āfrom.applescriptā and the compiled app āto.appā. It is the to.app that is the problem. Apple doesnāt;t like the app name being ātoā.
I changed it to ātodoā and everything worked fine and no āmissing valueā. The last item returned is ātodoā.
Regarding your edit: No, the name to is simply what I used to post the question. On my MacBook, the input file was quit-all.applescript and the outfile was quit-all.app.
I just tried to compile the same input file to:
quit-all.app (once again, just in case)
quitall.app
quit.app
qui.app
qu.app
q.app
todo.app
And no matter of the name of the outfile file, the error persists. macOS 15.3.2. Are you sure it worked because of renaming and not because of something different?
* * *
As a workaround, I tried to create an executable shell script instead:
I did some testing and Iām pretty sure I know what is causing this issue.
The line of John202307ās app that begins with set bundleIDs... finds the AppleScript app as a process and returns missing value for that process because the app does not have a bundle identifier. Then, the line that begins with if theID is... is unable to quit missing value and reports an error.
There are a number of ways to fix this:
As Robert suggests, include missing value (the AppleScript constant not quoted text) in the whitelist.
Save or resave the app with Script Debugger with a bundle identifier and include that bundle identifier in the whitelist (see screenshot below).
Save or resave the app with Script Debugger with the Applet is background only option enabled (see screenshot below):
Yes, your last script works for me, thanks! macOS 15.3.2, the script ā that is, the app ā works from Finder as well as from the Finder toolbar.
Have you tried to make it into an app using āScript Editorā
Yes, this method works as well! Good to know. That is, if compiling with Script Editor, I can use my original script.
* * *
Regarding the filename: Iām not sure I understand you correctly, but if you mean that I can simply take my original script, compile it using osacompile to an app with a filename e.g. todo.app and this will be enough to make it work without having the error window, this doesnāt work. By using these steps, I wasnāt able to get rid of the error window.
@robertfern Maybe you could suggest how to modify your version so that it will quit only the apps that donāt have open windows?
Update: Nevermind, I figured it out.
property white_list : {"com.apple.finder", "com.apple.Terminal"}
tell application "System Events"
set appProcesses to processes whose background only is false
end tell
repeat with appProcess in appProcesses
try
set theID to bundle identifier of appProcess
if theID is not in white_list then
tell application "System Events" to set winCount to (count of windows of appProcess)
if winCount is 0 then tell application id theID to quit
end if
end try
end repeat
FWIW, a while back I looked at various AppleScripts that quit the active apps. I decided to use a variant of a script written by Shane, and Iāve included that below. I tested this script as an AppleScript app run by way of an icon in a Finder window toolbar, and it worked fine.
Itās important to note that this script uses two frameworks, which take 350 milliseconds to load on my Sequoia computer. However, I run this script by way of FastScripts, which preloads both of these frameworks, so this requirement is not an issue for me. Also, these frameworks, once loaded, tend to stay in memory, so this requirement would not be an issue in this circumstance either.
use framework "AppKit"
use framework "Foundation"
use scripting additions
on main()
set doNotQuit to {"Finder", "Script Editor", "Script Debugger"} --edit as desired but must include Finder
set theApps to current application's NSWorkspace's sharedWorkspace()'s runningApplications()
set thePredicate to current application's NSPredicate's predicateWithFormat:"activationPolicy == 0 AND NOT (localizedName IN %@)" argumentArray:{doNotQuit}
set theApps to theApps's filteredArrayUsingPredicate:thePredicate
repeat with anApp in theApps
anApp's terminate()
end repeat
--tell application "Finder" to close every window --enable if desired
end main
main()
john202307. The NSWorkspace line creates an array (aka list) of all running applications. The NSPredicate line creates a filter which is somewhat analogous to an AppleScript whose clause. Thus, for example, both might be used to remove from an array or list all files that do not have a particular name extension. The benefits of an NSPredicate filter are that it is very fast and the filters can be quite elaborate.
My implementation of Shaneās script is written in AppleScript Objective-C. The use framework "Foundation" statement tells the script that commands and other statements in this framework are going to be used, while a tell application "Finder" statement directs the script to look in the AppleScript Finder class for the commands and other statements that follow.
Iāve been using that script for a long time, and, unfortunately, I donāt have a link to the original topic.
The only thing that would make this script perfect, is if it had the open applications āaskā to save any changes. As I have no idea if that would be a lot of effort, or a few minor changes/additions, thought Iād ask.
I just saved copies of the script as an app to my Desktop with Script Editor and then Script Debugger. In both instances, double-clicking on the app closed all open apps (except those in the doNotQuit list). The script doesnāt require that anything be installed. The only issue might be if you have a really, really ancient version of macOS. Or, perhaps thereās some Privacy & Security setting that preventing the script from executing, but if thatās the case there should be an error. Thatās odd.
Homer712. The script will either automatically save or prompt to save an appās unsaved work depending on your macOS settings. That Iām aware of, itās not possible for the script to change the macOS setting. BTW, Iāve been using this script for several years and have never once lost any unsaved work.