Is it possible for Applescript to call an application by process ID or some unique identification other than by name? One of my apps can launch multiple instances of itself, and each instance has the same name as the first instance. In my script, I get the name of the current application, then process some stuff, then activate the application again to paste in some data.
The problem is, when the script activates the application again, if there are multiple instances running, it will activate the first instance that was launched, rather than the one that was current at the time the script was run. My guess is this is because it’s calling the app by name, and there are multiple apps running with the same name!
So, is there some way other than by name, that I can refer to an active application?
You can get the id of a process from “System Events”:
tell application "System Events" to set F to id of process "Finder"
-- then use it:
tell (process id F) to set P to path to desktop as alias
I think your guess is right too. The second instance may be listed after the first because it has a higher id.
Thanks, but I cannot get your script to compile. Runs into trouble here
. Says
Sorry, CJ;
The System Events tell block has to include the second tell. I tested that in my script, and screwed up getting it into my post. Oops. /adam
tell application "System Events"
set F to id of process "Finder"
-- then use it:
tell (process id F) to set P to path to desktop as alias
end tell
I must ask why you’re launching multiple instances of your application in the first place. What task(s) are you trying to accomplish?
I had to run several instances of VLC in order to analyse DVD’s of surgical footage taken with several cameras in the same operation. The above commands will be most helpful in controlling these instances. Thanks!
The obvious question, PJ, is how do you start the second instance of VLC from an AppleScript?
Mikey-san, I’m running an app called ArchiCAD (architectural CAD software). The app only allows one document to be open at a time, however it allows you to open multiple documents by launching multiple instances of the app. However, the app is always named “ArchiCAD” so the Finder cannot tell which instance I am referring to.
The revised code worked, Adam, thanks. I am trying to get the id of the current, or frontmost, application, but this isn’t working. I was using the following code to get the name of the application, but it doesn’t work to get its id.
set real_name to name of (info for (path to frontmost application))
So I tried this approach, but it didn’t work, either.
set F to id of frontmost application
ArchiCAD does not allow you to specify a text box as being either all caps, lowercase, etc. So, to convert lowercase type into all caps, you’d have to re-type the whole text entry. I’m using an applescript to copy the text to the clipboard, then process the lowercase text to uppercase using a comparison string of text, copy the result back to the clipboard, then paste it back into ArchiCAD. It worked great until this new version allowed multiple instances of ArchiCAD (not possible before this latest release).
This script (built on a hint from Kai) will find the diplayed name / ID pairs for every running application that is not in the background. You can get the IDs from there.
set name_id_pairs to {}
tell application "System Events"
set AP to application processes where it is not background only -- this from Kai
repeat with anApp in AP
set end of name_id_pairs to {displayed name, id} of anApp
end repeat
end tell
name_id_pairs
or something like this:
--set name_id_pairs to {}
set iCal to {}
tell application "System Events"
set AP to application processes where it is not background only
repeat with anApp in AP
if displayed name of anApp is "iCal.app" then set end of iCal to id of anApp
--set end of name_id_pairs to {displayed name, id} of anApp
end repeat
end tell
name_id_pairs
Adam,
It’s highly unsatisfactory, and proably quite sloppy, but the only way I could find to do it was this:
do shell script "/Applications/VLC.app/Contents/MacOS/VLC"
I saved this as an application on its own, because it always freezes, and I have to force-quit.
However, it does the job and opens a new instance of VLC.
Is there a better way?
PJ.
Comments on the second script above:
Normally, if you were searching a list for a single instance, you’d include an “exit repeat” in the test sequence when you found it - no need to test the rest. In this case I didn’t because you have two instances and they may not show up one after the other.
Got it :lol:
tell application "VLC" to launch
tell application "VLC_copy" to launch
tell application "System Events"
set vlc to displayed name of every process whose name contains "VLC"
set vID to id of every process whose name contains "VLC"
end tell
set vlcProc to {}
repeat with k from 1 to count vlc
set end of vlcProc to {item k of vlc, item k of vID}
end repeat
vlcProc -- {{VLC.app, 64356353}, {VLC_copy.app, 64487425}}
Okay, so I am able to get the process id of the current application, but I am unable to use that process id to refer to the application! In the script below, for example, it works fine running out of Script Editor. If you highlight a word and run the script, you’ll see your selected word appear in the dialog box. However, if you save and run the script from, for example, Text Edit the clipboard remains empty!
It seems like the “tell process proc_id” line isn’t working. I’ve tried “tell application whose id is proc_id” but that doesn’t work, either. Any ideas?
tell application "System Events"
set proc_id to id of application processes where it is frontmost
tell process proc_id
set the clipboard to ""
delay 0.5
keystroke "c" using command down
delay 0.5
end tell
display dialog (the clipboard)
end tell
I’ve got this much working:
tell application "VLC" to launch
tell application "VLC_copy" to launch
tell application "System Events" to set vlc to {displayed name of every process whose name is "VLC", id of every process whose name contains "VLC"}
repeat with aNum in (item 2 of vlc)
tell application "System Events"
set frontmost of process id aNum to true
delay 1
set visible of process id aNum to false
delay 1
end tell
end repeat
and this works:
tell application "VLC_copy" to quit
tell application "VLC" to quit
More than one way to skin a cat:
property vlc_1 : "VLC"
property vlc_2 : "VLC_copy"
tell application vlc_1 to launch
tell application vlc_2 to launch
tell application "System Events" to set vlc to {displayed name of every process whose name is "VLC", id of every process whose name contains "VLC"}
-- way number 1
repeat with aNum in (item 2 of vlc)
tell application "System Events" to set frontmost of process id aNum to true
end repeat
-- alternative approach
(*repeat with anID in item 2 of vlc
tell application "System Events" to tell process id anID
set frontmost to true
tell window 1 to if exists then
perform action "AXRaise" -- brings a window to the front.
end if
end tell
end repeat*)
Here’s the piece of script I’m working on. So far, I’'m still stuck trying to tell the application using its process id to do anything! The tell command using keystroke “c” should have copied the block of text I had selected to the clipboard, but when the display dialog (the clipboard) command comes up, the clipboard is always empty. I know that the process id of the current app is working from line 2, but I can’t figure out how to refer to that app using its id.
tell application "System Events"
set the clipboard to ""
set proc_id to id of application processes where it is frontmost
--display dialog proc_id
tell process id proc_id
keystroke "c" using command down
delay 1
end tell
set source_text to the clipboard as string
set this_item to source_text
set this_item to my change_case_of(the source_text, "upper")
set the clipboard to this_item
display dialog (the clipboard)
end tell
on change_case_of(this_text, this_case)
if this_case is "lower" then
set the comparison_string to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
set the source_string to "abcdefghijklmnopqrstuvwxyz"
else
set the comparison_string to "abcdefghijklmnopqrstuvwxyz"
set the source_string to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
end if
set the new_text to ""
repeat with thisChar in this_text
set x to the offset of thisChar in the comparison_string
if x is not 0 then
set the new_text to (the new_text & character x of the source_string) as string
else
set the new_text to (the new_text & thisChar) as string
end if
end repeat
return the new_text
end change_case_of
I don’t know what else might be troubling you, but proc_id in your script is a list of one item, and you want an integer:
set proc_id to (id of application processes where it is frontmost) as integer
tell application "System Events"
set proc to (id of processes where it is frontmost)
class of proc --> list
end tell
display dialog proc_id fakes you out because it coerces the list to a string for display purposes (not in the script).