I’m getting close to working out something that should help a lot with scripting, specifically involving FileMaker, but the question I have is a general one.
Is there a way to target a “tell application” block that uses that app’s own terminology at a specific copy of an application where there might be multiple copies running?
I already know how to get the process ID and then target a specific copy of the app for UI scripting with System Events, with a “tell process ” block. But, what I’m trying to do is be able to use the app’s own specific terminology (from its AppleScript dictionary).
I already know that I can get the desired application’s path (application file of the process), and use that with “tell application”. So, I’m close. BUT, it is possible to launch multiple copies of the SAME application file using a shell command like “open -n /Applications/MyProgram.app”. Then, both running copies of the app have the same application file, not just the same name.
Does anyone know if there is a way to do app-specific commands within a tell block that targets a specific copy?
In my specific usage, if there were two copies with the same app name AND the same app path, I’m trying to target the copy that is “frontmost”, so that’s an acceptable solution. But note, this is to use that app’s OWN dictionary commands - I already have a solution using process id for UI scripting commands.
Well, yes.
That’s how I could use commands from that app’s dictionary.
But, my question was how to direct those commands to a specific instance of the app.
Here’s an example, using an app that everyone has (my actual usage is FileMaker Pro). This might help you see what I’m talking about. The bit to notice is the admittedly unusual step of using “open -n” shell command to launch a 2nd separate process from the same source application path. In my original post, I did say that was the issue, and that telling the full path does not solve the question. But, this way you can try it out and see what the wrinkle is.
set myAppPosixPath to "/System/Applications/TextEdit.app"
tell application myAppPosixPath
set appName to name of it
make new document with properties {text:"Hello World Number 111111"}
end tell
tell application "System Events"
-- now, get the process ID of _this_ instance of the app so we can bring it to front later:
set procID_app1 to id of first application process whose name is appName
delay 0.5
end tell
-- open a 2nd copy of the SAME app, so it has the same application file path:
do shell script "open -n " & quoted form of myAppPosixPath
tell application "System Events"
delay 0.5
-- bring original app to front:
tell process id procID_app1 to set frontmost to true
delay 0.5
end tell
-- telling the SAME path talks to the 2nd app, even though it is NOT frontmost:
tell application myAppPosixPath
make new document with properties {text:"Hello World Number 222222"}
end tell
One potential answer is just to NOT use the “open -n” shell command to launch a 2nd process running of the exact same application file path. That’s what I will probably do.
My post here was just to see if anyone else happened to know something deeper that might still make it possible to “tell” a specific copy of an app at the same path, which is what my original post specified.
OK, I didn’t read your OP closely enough. Good luck.
This does not work:
tell application "System Events"
tell (process 1 whose name is "BBEdit")
using terms from application "BBEdit"
activate
set myText to text of window 1
end using terms from
end tell
end tell
One wouldn’t expect this to work. It’s non-sensical code. The activate command doesn’t act upon process class objects, so will probably throw a silent background error before being sent up the inheritance chain to the System Eventsapplication object. using terms from isn’t serving any purpose given that you don’t utilise any terminology that is specific to the BBEdit application dictionary. As such, window 1 references the System Eventswindow element belonging to the BBEditprocess object, and so doesn’t have a text property. Attempting to access it likely throws an exception, which should contain the full reference to the window object indicating whether it’s a child within the application "BBEdit" hierarchy or the application "System Events".
This is a question that has been asked fairly often over the years. As far as I know, it is not possible to target a specific application instance for sending Apple events, which seem to be received by whichever instance of a given application that was most recently spawned.
It might be possible to exert some control over this at a lower level, but that would involve manually constructing Apple events, which isn’t going to be worth the pay-off.
What is it you’re actually wanting to do with each specific instance of FileMaker ? As you have already gleaned, it is possible to target a specific instance of an application process to interface with its graphical elements by way of System Events. Of course, this won’t be very useful if you were needing to invoke a FileMaker command that is available only through its application dictionary, unless the same action can also be triggered via FileMaker’s menus or other manual user interaction.
A lot of what I do can be done (and must) via System Events. But, sometimes there are things that are better done with the app’s own dictionary.
I tried to explain in my original post that I had already covered the ground that some of the responses suggested, but was hoping maybe someone knew of something deeper.
Your response makes me think I’m already at the edge of what’s possible, unless, as you said, I did seem pretty tricky work directly constructing Apple Events. I haven’t dug into raw Apple Events for over 20 years, and probably won’t bother.
Thank you for confirming that I’m probably best off avoiding trying to launch multiple copies of the exact same app when I need to target app-specific dictionary commands.