Quit an application using AppleScript - macos

Whenever I try to quit an application using AppleScript I get the following error
An error of type -9874 has occurred.
The AppleScript command which I am using is
tell application "app_name"
quit
end tell

Are you sure that "app_name" exists ? If it does exist, are you sure that it knows how to respond to AppleEvents (is "AppleEvent-aware") ? Try the following test - launch Activity Monitor (in /Applications/Utilities) and run this script:
tell application "Activity Monitor"
quit
end tell
This works fine for me - if it works OK for you then the problem is probably with your specific application. If it doesn't work for you then you have some kind of system-related problem - try it on a different Mac to verify ?

Related

Apple Script application control

Thanks for reading my question. I have an issue I was hoping you could help me with. the following apple script will run but ends up timing out because the application is not selected; the icon just bounces on the mac server dock (OSX 10.85). What am I doing wrong?
tell application "(Application Name)"
activate
getURL "(Server URL)"
delay 30
tell database "(database name)"
do script "(Script Name)"
delay 60
close
end tell
end tell
do shell script "(Shell script path)"
Also, I'd like to tell the application to quit prior to running the shell script.
Any and all advice would be appreciated.
THANK YOU!
To quit an app, all you do is put a “quit” command inside its tell block, typically as the last command in the tell block:
tell application "Safari"
quit
end tell
Verify that “getURL” is the right command for the app you are targeting. The modern version is “open location.”
When you run your script from AppleScript Editor, you can tap on “Event Log” at the bottom of the window and see a log of events that occurred during your script’s execution. You can often see what went wrong there.
If your AppleScript is what is timing out, you can use with timeout:
with timeout of 3600 seconds
-- do something within an hour
end timeout
As jweaks said, you need to provide more information to get real help. Every application extends AppleScript in its own way. Your script may be perfect or it may not. There is no way for someone to know without knowing what application your script runs on. It’s like asking for help with Photoshop work but not telling anyone it is Photoshop you are working in.

Is it possible to write an applescript so that when I close one program it also closes another?

The example I can think of that is most relevant to me is to be able to close the last.fm app when I close iTunes. I quite often forget to close last.fm and I find it rather annoying. I'm sure there are other uses...
Yes you can.
Over on my Blog thecocoaquest I have two posts that cover this.
The first Post shows you a methods of doing this with a applescript and using a Launch Agent.
Applescript – Quit or Launch Application if another is or is not running
Here is one of the examples:
If I have one App running the second app will launch and will always be running while the first app is running.
Or when I quit the first App the second app will also quit
#!/usr/bin/osascript
#Copyright Mark Hunte 2012
#http://www.markosx.com/thecocoaquest/kill-one-application-if-another-is-not-running-applescript
set appMustBeRunning to "xcode"
set appToKill to "Snippets"
tell application "System Events"
set appMustBeRunningID to (unix id of processes whose name is appMustBeRunning)
set appToKillID to (unix id of processes whose name is appToKill)
end tell
if appMustBeRunningID is {} then
try
tell application "Snippets" to quit
end try
else if appToKillID is {} then
tell application "Snippets" to launch
end if
The Second post is a revision showing how to add more than one master & slave application
Applescript – Quit or Launch Application script.. ( Revised )
Also has an a script for if you just want to run the Applescript as an Application.

How to check in AppleScript if an app is running, without launching it - via osascript utility

Consider the following AppleScript:
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
set safRunning to is_running("Safari")
if safRunning then
tell application "Safari"
-- Stuff I only want executed if Safari is running goes here.
end tell
return "Running"
else
return "Not running"
end if
The problem: when I run this via the osascript command line utility, if Safari is not running, it gets launched and the script reports "Running". This is not the behaviour I desire or would expect. Note that it works as desired/expected when run within AppleScript Editor.
Is this an osascript bug / known issue? Or is it somehow intended behaviour for reasons I'm missing? Can anyone get it to work as desired? (BTW I'm running OSX 10.7.5; I can't see how to get osascript to report a version number).
If you comment out the tell / end tell lines, it behaves as I'd expect: if Safari is not running, it doesn't launch it, and prints "Not running". So it seems to me like the tell is what's causing Safari to be launched, but it doesn't need to be actually executed, just present in the script...? For a while I wondered if maybe this was just how tell is supposed to work, but since it doesn't work like this in AppleScript Editor, I guess not...
In fact, here's another, madder, version with similar behaviour:
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
set safRunning to is_running("Safari")
return safRunning
if false then
tell application "Safari"
end tell
end if
This still always launches Safari, even though tell is inside an if false block after the return statement! (But again, this is fine in AppleScript Editor.)
BTW, this behaviour isn't limited to Safari, but it also isn't universal:
Affected apps include: Safari, TextEdit, iPhoto, AppleScript Editor, iTerm, ...
Non-affected apps include: Google Chrome, iTunes, Preview, Mail, Terminal, Address Book, Echofon, ...
So, does anyone have any ideas about how I might fix or route around this? Is it an osascript bug? Or am I missing something about AppleScript's semantics?
For context: I'm trying to write a script (to be embedded/called from some python) which queries open browsers for the URLs of any tabs they have open; I've got it all working fine except that it always launches Safari, whether it's open or not. I've boiled down that undesirable behaviour to the simple test case shown above. I'm not aware of any way to run this script from python without using osascript, other than appscript, which I don't want to use because it's no longer developed/supported/recommended.
Many thanks for all inputs / insights!
I suspect the reason you are getting this is because each time you call the script from the command line with osascript the script is being compiled.
The act of compiling on a tell application will afaik make the app launch.
Calling the script from the command line with osascript from a pre-compiled file i.e .scpt does not cause this behaviour because the is no compiling to be done.
But calling it from a plain text (.txt,.sh ) file will so the app will launch.
If you do not want to use a .scpt file and want to use a plain text file then you could try the trick of putting a run script command in the applescript.
on is_running(appName)
tell application "System Events" to (name of processes) contains appName
end is_running
set safRunning to is_running("Safari")
if safRunning then
run script "tell application \"Safari\"
open location \"http://google.com\"
end tell"
return "Running"
else
return "Not running"
end if
The script in the run script is only compiled when needed. You will need to escape any characters like quotes as in my example.
It will be easier if you write the script in a normal applescript document first and compiled it to check for errors.
Then copy it to the plain text file.
UPDATE **
The method I used above was from a old script I had used to solved this issue a while before I answered here.
The answer works and is not trying to be elegant. ;-)
I actually like user1804762 method below. As it does work but feel the Answer is not clear enough so I will give an example on using it.
set appName to "Safari"
if application appName is running then
tell application id (id of application appName)
open location "http://google.com"
end tell
return "Running"
else
return "Not running"
end if
This script can be run from the command line with osascript
example:
osascript /Users/USERNAME/Desktop/foo.scpt
Notice that the script is saved as a compiled script. This will work ok and you can also save and use it as a plain text script.
i.e.
osascript /Users/USERNAME/Desktop/foo.applescript
Some Info:
"Enhanced Application Object Model":
tell application "iTunes"
if it is running then
pause
end if
end tell
You can also do it that way:
if application "iTunes" is running then
tell application "iTunes" to quit
end if
You can also do this:
get name of application "iTunes"
get version of application "iTunes"
And to complete the journey:
get id of application "TextEdit" --> "com.apple.TextEdit"
tell application id "com.apple.TextEdit"
make new document
end tell
That was the "Enhanced Application Object Model". If an app still launches (for example, the first time you compile & execute the script) I assume it is because AS has to get some info from the app which it did not found in the dictionary (or something like that...?).
OK, I know this question is really old, but I stumbled on it looking for a different issue and had to pipe in considering how complicated some of these responses are.
The simple code to achieve what you want(ed) is:
tell application "System Events"
if application process "Safari" exists then
-- do stuff you want to do only if Safari exists
end if
end tell
On older systems, the syntax used to be:
tell application "System Events"
if exists of application process "Safari" is true then
-- do stuff you want to do only if Safari exists
end if
end tell
One of these should definitely work for you, intrepid searcher of Applescript solutions for action only when an app is running.
Oh! Bonus tip: And if you're not sure what the application process name is exactly (it is usually but not always the app name), before coding your final script run…
tell application "System Events"
get every application process
end tell
And find your app process name in the results.
Here's a screen grab of running that command. (Note the zillions of Google Chrome Helper instances. Thanks Google!)
HTH!
tell application "Finder"
set applicationsnames to get the name of every process whose visible is true
end tell
set appName to "Safari"
if applicationsnames does not contain appName then
say (appName & " is not running")
--add here what you want to happen
end if
return applicationsnames
This is returning {"Finder", "JavaAppLauncher", "firefox", "Microsoft Word", "iTunes", "AppleScript Editor"} for me
Hope this helps
All the previously made answers suffer from the same issue, though:
They look for the app by its name. However, the user may rename the app, and then the script will believe the app does not run, when in fact it does.
To properly check for a running app, it should be found by its bundle ID, which the user cannot change.
The bundle ID can be inquired with this command, for instance, when the app is already running:
tell application "System Events"
get bundle identifier of application process "Safari"
end tell
Or like this for any installed app:
get id of application "Safari"
To check whether an app with a particular bundle ID is running, use this code:
tell application "System Events"
set ids to bundle identifier of every application process
if ids contains "com.apple.safari" then
return "Running"
else
return "Not running"
end if
end tell
Furthermore, here's an example to check if an app is running, then quit it, then relaunch it, ensuring that the very same app is relaunched that was running before, and not some other copy that may also exist:
set bundleID to "com.apple.safari"
set apps to runningApps(bundleID)
set appCount to length of apps
if appCount is not 0 then
quit application id bundleID
repeat while length of runningApps(bundleID) = appCount
-- wait for the app to quit
end repeat
open first item of apps
end if
on runningApps(bundleID)
-- The try block is to catch the rare case of having more than one
-- copy of an app running at the same time. Unfortunately, in that
-- case this code will not run as expected, because we don't get the
-- correct list of multiple items back then. But at least the script
-- will not crash from it but handle it gracefully.
tell application "System Events"
try
return application file of (every application process whose bundle identifier = bundleID)
end try
end tell
return {}
end runningApps
I had the same problem as described here trying to set up an AppleScript (triggered by a BetterTouchTool gesture) that plays/pauses VLC or iTunes, but only iTunes if VLC is not running (due to my workflow) and, naturally, only VLC while it's running. (I use the automatic pause/play trigger for iTunes in VLC's settings, for launch and quit of the app.)
VLC was always launched on the first use of the BetterTouchTool-trigger after every relaunch of BTT as the dictionary-cache is deleted at that point and the AppleScript handler has to launch every scripted application if a tell is aimed at it in order to call its dictionary.
I didn't find anything that avoided this anywhere; there were some attempts, but none worked for me as the dictionary-call by the script handler is nothing we can influence. I came up with this dirty workaround:
Create a separate AppleScript file only containing the line that includes the tell for VLC
Save it at some place where it won't annoy you
Replace the line containing the tell in the original AppleScript with a line that runs that script
This will lead to the first compilation of the script not calling the application (VLC, in my case) directly, only the script, which means that the application will not need to launch.
VLC will need to launch once that separate file is called, but, well, if you call that file in order to tell VLC something, you will have VLC already opened (or will want it open) anyway.
The AppleScript I call through my BetterTouchTool-trigger (a specific tap on the trackpad, in my case) looks like this:
if application "iTunes" is running and not application "VLC" is running then
tell application "iTunes" to playpause
end if
if application "VLC" is running then
run script "/Users/jannis/bin/PlayVLC.scpt"
end if
The separate AppleScript file ("PLayVLC.scpt, saved in a folder called "bin" in my user folder which I created manually ages ago for such purposes) is just this:
tell application "VLC" to play
If you open that script manually, it will of course also launch VLC. But that hopefully won't be necessary often, or ever.
I actually have no idea if this creates any deeper problems I don't know of as I'm not a pro coder; if so, please notify me. I hope this helps anyone!

infinite loop in applescript stops logout

So I am writing a basic applescript to end a very annoying program that randomly opens and interrupts me while Im working. The program needs to stay but i don't want to see it. I want my script to open automatically when the computer restarts (I did this in settings). I want to test to make sure it works but upon saving it as an application I cannot logout or shutdown or restart without manually force quitting. I assume this is because of the repeat loop but i don't know how to fix this. Ive tried everything i could think of. Any help would be greatly appreciated. thank you
on appIsRunning(appName)
tell application "System Events" to (name of processes) contains appName
end appIsRunning
repeat
if appIsRunning("LiveUpdate") then
tell application "LiveUpdate"
quit
end tell
end repeat
I'm not sure you have the proper approach either. However, if you want to do what you are trying to do then you want to create a stay-open application. You do that by saving the applescript as an application and checking the "stay open after run handler" checkbox. Here's how you write the code for that...
on idle
if appIsRunning("LiveUpdate") then tell application "LiveUpdate" to quit
return 10
end idle
on appIsRunning(appName)
tell application "System Events" to (name of processes) contains appName
end appIsRunning
Notice the "on idle" handler. That is the handler that is repeatedly run while the application stays open. Notice that I have placed "return 10" at the end of that handler. That determines how often the idle handler runs, in this case every 10 seconds. You can change that to what you want.
The advantage of this method is that you can quit this stay-open application. You won't get stuck in a repeat loop that you can't quit.
You mention that you do not want to see this application while it is running. To make that happen you will have to modify the info.plist file inside the application bundle (right-click on the application and show package contents). You have to add the "LSUIElement" key to the plist and give it a value of true. Then you won't see the application in the Dock while it's running.
Because you can't see it running you will need some way to quit the application. You can do that either using another applescript...
tell application "My Stay Open Application" to quit.
Or you can open activity monitor and quit it from there. Good luck.
Here is another approach:
on idle
if application "LiveUpdate" is running then tell application "LiveUpdate" to quit
return 10
end idle

Error code -10810 when calling "open" from applescript

I'm trying to use AppleScript to modify some app settings. The code looks like this:
#!/bin/sh
echo '
tell application "Finder"
tell disk "'$1'"
open
set current view of container window to icon view
...
close
end tell
end tell
' | osascript
However, I keep on getting a -10810 error code when applescript hits "open" ("64:68: execution error: An error of type -10810 has occurred. (-10810)"). I've done some googling and all I got was "reboot and wait, it sometimes magically starts working" (it didn't).
The machine is running Mac OS Server 10.6. I though it perhaps might be some permissions issue, but running the command as root returns the same error.
Update: Solved (well, more or less :-) ). The thing is that "open" needs a UI. And the problem was that I was using ssh to run the script (which I didn't mention here, because I didn't think it was relevant). So there was no UI. It works when I log in using VNC first.
Solved (well, more or less :-) ).
The thing is that "open" needs a UI. And the problem was that I was using ssh to run the script (which I didn't mention here, because I didn't think it was relevant). So there was no UI. It works when I log in using VNC first.

Resources