Check if an application exists using AppleScript - applescript

This code does not work for apps that do not exist because it prompts the user to look for "FooApp" (and I don't want to interact with the user):
get exists application "FooApp"
This code only works for apps whose process name matches its application name, which covers most but not all applications:
tell application "System Events"
get exists application process "FooApp"
end tell
(For example on my machine "OmniGraffle Professional" is a process name but the corresponding application name is "OmniGraffle Professional 4".)

#regulus6633 is right to point out you’re doing two separate things in your examples, and also his advice about bundle identifiers is spot on.
My preferred way to check if an application is installed is the following:
try
tell application "Finder" to get application file id "bundle.id.here"
set appExists to true
on error
set appExists to false
end try
This avoids the “Where is application x?” dialog and assigns a boolean value to appExists. You could also display alert in the on error block (or anything you desire).
For your second example, you could write:
tell application "System Events"
set processIsRunning to ((bundle identifier of processes) ¬
contains "com.bundle.id.here")
end tell
It does almost exactly what #regulus6633’s code does, but grabs the list of processes and checks it in a single line. You also don’t have to worry about initialising processIsRunning.
If you're using application names just swap bundle identifier for name.

Notice that your 2 scripts do different things. The first one checks if it is on the computer. The second one checks if it is currently running. So here's how to do the first thing.
set doesExist to false
try
do shell script "osascript -e 'exists application \"foo\"'"
set doesExist to true
end try
return doesExist
And note that as you point out some applications have a variety of names. In those cases you can use the bundle id of the app instead of it's name. Here's how to get the id of Safari and use it...
set appID to id of application "Safari"
exists application id appID
And if you wanted to see if it is running, like in your second script, you could do this...
set processIsRunning to true
tell application "System Events"
set runningProcesses to processes whose bundle identifier is appID
end tell
if runningProcesses is {} then set processIsRunning to false
return processIsRunning

This is an old question but the answer may still be helpful. The following shell script doesn't launch the application, avoids the "Where is application x?" dialog if the application doesn't exist, accepts either the application name or bundle id as input, and returns the application's bundle id if it exists or an empty string if it doesn't:
set appBundleId to do shell script "osascript -e " & ("id of application \"" & appRef & "\"")'s quoted form & " || osascript -e " & ("id of application id \"" & appRef & "\"")'s quoted form & " || :"
set doesExist to (appBundleId ≠ "")
where appRef is either the application name or bundle id.

Another way of doing this, should you have two applications with the same bundle identifier, is to use the application names. For instance, Adobe InDesign CS5.5 and Adobe InDesign CS6 both have com.adobe.InDesign as their bundle identifier.
tell application "System Events"
name of every process contains ("Adobe Photoshop CS5.5")
end tell

Related

Is there an application type in applescript?

Is there an application type in AppleScript?
I have this handler:
on doHandler(theApplication)
set theApp to ("\"" & theApplication & "\"")
tell application theApp
set frontWindow to theApp's (window 1)
etc.
end tell
end doHandler
It is accessed as follows:
doHandler("TextEdit")
This produces the obvious error on theApp's (window 1).
So, what is the correct call?
This cannot work. The argument of tell application must be a literal string because the terminology is evaluated at compile time.
Apart from that the code doesn't work anyway because it expects that every application has an AppleScript dictionary containing a window property which is not the case.
All you need to do is eliminate the line set theApp to... and use the its keyword to set up the correct reference.
doHandler("TextEdit")
on doHandler(theApplication)
tell application theApplication
set frontWindow to its (window 1)
end tell
end doHandler
In the main script, application references are established at compile time, so you can't have a variable app name, but handlers aren't evaluated until run time.

Can't get POSIX Path of given application in Applescript

I've written some Applescript to create a list of paths of all
applications running in the dock:
set appsRunning to []
tell application "System Events"
repeat with p in every application process
if background only of p is false then
set appsRunning to appsRunning & POSIX path of (path to application p)
end if
end repeat
end tell
But when it runs I get
the error - "Can't make application into type constant" and it
highlights path to application p.
I don't understand why this happens because when I run
set q to POSIX path of (path to application "Finder") -- or any other application
I get no error whatsoever and I see
"/System/Library/CoreServices/Finder.app/" returned in the Results
field.
How can I get this to work?
P.S. For my purposes it is essential that I get the path - the
application name simply won't do. (This is because when I get the name
of the application process, some of my applications which are SSBs
made using Fluid return "FluidApp" as their
name instead of "Gmail" or "Tumblr" or whatever site it is that
I've made into an application. I need to distinguish between these and
that only happens when I get the path.)
Any help would be appreciated! Thanks.
Update: I used an amended version of the first suggestion in #vadian's answer to solve my problem:
set appsRunning to {}
tell application "System Events"
repeat with aProcess in (get application file of every application process whose background only is false)
set appsRunning to appsRunning & POSIX path of aProcess
end repeat
end tell
The element application process of System Events has a property application file, which you can get the POSIX path directly from.
set appsRunning to {}
tell application "System Events"
repeat with aProcess in (get every application process whose background only is false)
set end of appsRunning to POSIX path of application file of aProcess
end repeat
end tell
or easier
tell application "System Events"
set appsRunning to POSIX path of application file of every application process whose background only is false
end tell
additional here a solution which excludes the Finder because it runs all the time and the path is fixed
tell application "System Events"
set appsRunning to POSIX path of application file of every application process whose background only is false and name is not "Finder"
end tell
set end of appsRunning to "/System/Library/CoreServices/Finder.app"
another solution using your original approach
set appsRunning to {}
tell application "System Events"
set applicationNames to get name of every application process whose background only is false
end tell
repeat with aName in applicationNames
set end of appsRunning to POSIX path of (path to application aName)
end repeat
and last but not least the AppleScriptObjC version (Mavericks and higher, in Mavericks only in a script library)
set appsRunning to (current application's NSWorkspace's sharedWorkspace()'s launchedApplications()'s valueForKey:"NSApplicationPath") as list
Though the method launchedApplications of NSWorkspace is deprecated, it works in Yosemite
to use the AppleScriptObjC in a script library save this code
use framework "Foundation"
on launchedApplications()
return (current application's NSWorkspace's sharedWorkspace()'s launchedApplications()'s valueForKey:"NSApplicationPath") as list
end launchedApplications
as script bundle (in Mavericks you have to check "AppleScript/Objective-C library" in the side bar of the script) in ~/Library/Script Libraries. Create the folder if it doesn't exist.
Now you can call the script library from a normal script file (the script library is named "NSWorkspace.scptd")
use script "NSWorkspace"
set appsRunning to launchedApplications() of script "NSWorkspace"

Having trouble with remote folder actions with AppleScript

So I have an Applescript to help with naming photo's appropriately for data entry to assign it to a Unique ID. Since we're using Mac's this is done in AppleScript. This works great but it's only for one machine. What is now needed is to work on multiple machines. What I want to do is put the photos on our server and have the client machines do the action on the folder from there.
The problem I am currently having is that the script does not authenticate the user and does not run the script even though the info is correct. Am I doing this correctly?
tell application "Finder" of machine "eppc://user:password#server.local"
set renameFiles to the selection
set inventoryFiles to every file in folder (((path to documents folder) as text) & "Inventory Photos")
set currentIndex to the count of inventoryFiles
repeat with i from 1 to the count of renameFiles
set currentFile to (item i of renameFiles)
set new_name to ((10000 + currentIndex + i) as text) & ".jpg"
set name of currentFile to "a" & new_name
end repeat
end tell
Thank you for any help

How to get filename without extension from Omnigraffle?

I'm trying to get the filename without the extension of the current document file in Omnigraffle Professional 5.
tell application "OmniGraffle Professional 5"
set _document to front document
set _path to path of _document
-- Get filename without extension
tell application "Finder"
set {_filename, _extension, _ishidden} to the
{displayed_name, name_extension, extension_hidden} of the _path
end tell
end tell
This gives me the following error: error "Can’t get displayed_name of \"/Users/ca/Downloads/Feb 8.graffle\"." number -1728 from displayed_name of "/Users/ca/Downloads/Feb 8.graffle".
I found some related questions and pages, but I'm a bit lost and really can't understand why it does not work.
Applescript: Get filenames in folder without extension
Applescript Help...Just the File Name
Thanks for your help!
You'd need to change it to the following:
tell application "OmniGraffle Professional 5"
set _document to front document
set _path to path of _document
-- Get filename without extension
tell application "Finder"
set {_filename, _extension, _ishidden} to the ¬
{displayed name, name extension, extension hidden} ¬
of ((the _path as POSIX file) as alias)
end tell
if (_extension ≠ missing value) then
set baseName to text 1 thru -((length of _extension) + 2) of _filename
end if
end tell
"path of front document" returns the POSIX path of a file, which is just a plain string. To be able to get information on an item the Finder will want an alias reference to the file in question. When you pass a plain string it gets an error because a plain string won't have those properties. To get an alias, you need to coerce the plain path first to a POSIX file and then coerce the POSIX file to an alias.
Unless you have defined these variables elsewhere, you need to remove the underscores in {displayed_name, name_extension, extension_hidden}. When you look at the "compiled" code with those underscores left in, it looks like in the following image:
So, the AppleScript is interpreting displayed_name to be a variable, not a property. Now, that's fine if you've defined those variables elsewhere, such as at the top of your script in properties. But if not, you need to remove the underscores, as the property names of Finder items don't have underscores in them. When you remove the underscores, the coloring appears correct (properties are purple with the variables being green).
Note that that still won't give you the filename without an extension. To get that, you'd need to do something like I did in the added line using text n thru m
if (_extension ≠ missing value) then
set baseName to text 1 thru -((length of _extension) + 2) of _filename
end if
First, you need to use the correct labels for the properties of whatever application you are targeting - these can be found in the application scripting dictionary. The next problem is that the Finder doesn't know anything about POSIX paths, which is apparently what OmniGraffle is returning for the document path, so you need to coerce the path into something that the Finder does know about, such as an alias.
tell application "Finder"
set {_filename, _extension, _ishidden} to the {displayed name, name extension, extension hidden} of (_path as POSIX file as alias)
end tell

AppleScript Word Count Service

I am trying to create a service in OSX leopard that counts the number of words of selected text. I have automator set to run an applescript, with the following put in it:
on run {input, parameters}
count words of input
display alert "Words: " & input
return input
end run
When I compile the script, it says it cannot count every word. What am I doing wrong?
Thanks for the help,
Elliott
First of all, I presume you are testing this in Automator, and that's where the error is taking place? If so, the likely problem is that there is no input—so it can't count the words of nothing. In order to test it successfully, you need to temporarily add a "Get Specified Text" action before the Run AppleScript action, and enter some test text into that field. You'll have to remove the Get Specified Text action before using it as an actual service.
Secondly, you need to use
count words of (input as string)
in order to get a proper count, otherwise it'll return zero.
I made one here, on Github:
https://gist.github.com/1616556
The current source is:
on run {input, parameters}
tell application "System Events"
set _appname to name of first process whose frontmost is true
end tell
set word_count to count words of (input as string)
set character_count to count characters of (input as string)
tell application _appname
display alert "" & word_count & " words, " & character_count & " characters"
end tell
return input
end run
Use Automator.app to create a new service, and then select the Run AppleScript action. Paste this code in to the text box, and save as Word and Character Count. Now switch to a new app, select some text, and open the context menu to find the new option.

Resources