I would like to create an executable file that opens an application if it is not currently open, and quits the application if it is already open.
I would also like the window of the application to be hidden after it opens.
I already figured out that the terminal command osascript -e 'tell application "Finder"' -e 'set visible of process "KeyboardCleanTool" to false' -e 'end tell'
will hide an application after it is open, so this command would also need to be integrated into the executable file.
The application is called KeyboardCleanTool
and is stored at /Applications/KeyboardCleanTool.app
(macOS Catalina)
Best Answer
You would be best advised to either create the application from within Script Editor as an actual AppleScript app written in AppleScript; or to create an executable shell script program that is written in shell script without calling out to
osascript
. There's nothing wrong per se about mixing it up, and indeed there's lots of situations where it's needed or useful, but this isn't one as both scripting languages have their own dedicated mechanisms for doing what you need. I'll show you both example scripts:AppleScript
First, I'd recommend running a quick line of AppleScript to obtain the bundle identifier of
KeyboardCleanTool
, which is one way to allow AppleScript to reference an application without having that application launch as a result without an explicit request for it to do so (some applications do this because their AppleScript dictionary only avails itself to be read by AppleScript if the application is running).So, run this line, then you can dispose of it after taking a note of the result:
It'll probably be something like
"com.hegenberg.KeyboardCleanTool"
. That's what I'll use in the script below, which you can replace with the correct bundle identifier:There are three ways to open applications using AppleScript, each with different results:
activate
opens the application, brings it to the foreground, and gives it focus;launch
opens the application and reveals the windows but doesn't bring them into the foreground, nor gives it focus. The windows will be obscured behind whatever application currently has focus, and possibly others (I don't recall fully, but the newly launched app might sit at the back of the application z-ordering);run
opens the application but neither shows its windows nor gives it focus. For applications that have neither a dock nor menu bar icon, you won't be given any signal that it has been opened. This is the command it sounds like you want.Using
tell application "Finder" to set visible of process "KeyboardCleanTool" to false
is not a great method. Firstly, you shouldn't use Finder for controlling the GUI, which is what this is doing; use System Events, which was created specifically to take the job away from Finder because Finder can't even do its own job properly without having a melt down, let alone trying to prioritise calls to manipulate the UI.It also requires additional permissions that I'm sure you've already granted, but is worth mentioning for other users who don't wish to do this.
Lastly, if you don't need call in outside help to do something, it's much more advantageous (quicker, more efficient, less demanding on resources) to use a means already availed to you by the core scripting commands.
To create an Application using the above script: Save the script in Script Editor, selecting the type from the drop down list in the Save dialog that is called something like "Application bundle" or "AppleScript Applet". You'll know it when you see the four options. It can be saved anywhere you like, but a sub-directory in your user applications folder would be a sensible choice, i.e.
~/Applications
, or the root applications folder,/Applications
if you prefer.Shell Script, e.g.
bash
Let me know if you use a shell other than
bash
, and I'm aware Catalina is packaged withzsh
and I, myself, preferentially useFish
and recommend you check it out.The
bash
script for the task at hand can be this:This can be saved as anything you like, and ideally in a directory that is listed in your
$PATH
environment variable, such as _/usr/local/bin
. It will also need to be made executable. Taking the above script, here's the entirebash
code that will do all this:Once that's done, you can invoke the program like this:
And, of course, you don't need to save the program in
/usr/local/bin
. Saving it in your main/Applications
folder is perfectly fine. It will have an icon representing a Terminal shell, but you can treat it like any other application: double-click to run from within Finder and it will exit when it's done.