AppleScript_ The Definitive Guide - Matt Neuburg [209]
tell application "Finder" of machine "eppc://duck.local"
display dialog "Watson, come here, I want you."
-- error: Finder got an error: No user interaction allowed
end tell
The scripting addition commands store script and run script are disabled, probably as a security measure (but load script works).
Passing object references back and forth between machines can work, because the reference is usually endowed with a machine specifier as well as an application specifier. But aliases can't usually be handed between one machine and another, because they are resolved on the wrong machine; instead, try to obtain a pathname string.
You cannot target a remote machine merely; you must target some application on that machine. This raises the question of how to launch a remote application in order to target it. You cannot simply target the application by name as a way of launching it, because a literal application specifier will be resolved on the local machine. A remote application must thus already be running before you target it. Accordingly, you must always start with some application you know is running; likely possibilities are Finder and Dock. Then you can worry about whether the application you want to target is running. Here's how to find out:
set s to "eppc://mattneub:teehee@duck.local/Finder?uid=501"
using terms from application "Finder"
tell application s
get name of every process
-- {"loginwindow", "Dock", "SystemUIServer", "Finder", "LaunchBar",
"UniversalAccess", "System Events"}
end tell
end using terms from
In theory you shouldn't be able to talk like that, because the Finder no longer handles the process class—System Events does (see "System Events," later in this chapter). However, the process class is grandfathered into the Finder, and as a bonus, it is implemented by routing the Apple event to System Events, so not only do you get the answer, you also cause System Events to launch, which is good because you might want to target it.
This still doesn't answer the more general question of how to launch an application remotely. If you know its full pathname, then you can just tell the Finder to open it:
tell application "Finder" of machine "eppc://duck.local"
open item "OmniumGatherum:Applications:Utilities:Terminal.app"
end tell
Otherwise, the official solution is to ask the Finder to open the application file using its ID , which can be a four-letter creator code or the application's bundle identifier. Thus, this works even if BBEdit is not running:
set m to "eppc://mattneub:teehee@duck.local"
tell application "Finder" of machine m
using terms from application "Finder"
open application file id "com.barebones.BBEdit"
end using terms from
end tell
tell application "BBEdit" of machine m
using terms from application "BBEdit"
set contents of document 1 to "Hello, world!"
end using terms from
end tell
(It is also possible to launch an application remotely using do shell script and osascript, but I'm told that this is regarded as a security hole and may be closed.)
If multiple users are logged into the remote computer simultaneously, you can target a specific user with the uid parameter of the machine specifier. Indeed, you really should do so, because otherwise you can't be certain which user you're talking to (AppleScript seems to decide this in a somewhat random manner; I regard this as a bug). Again, the choose remote application dialog can be helpful here, as it distinguishes applications running under different users and tells you the user's uid number. Another approach is trial and error: just throw uid numbers at the machine and try to communicate with a running application, and see if you get an error or not:
set L to {}
repeat with i from 501 to 520
set m to "eppc://mattneub:teehee@duck.local/?uid=" & (i as string)
using terms from application "Finder"
try
tell application "Finder" of machine m
get (desktop as string)
set end of L to i
end tell
end try
end using terms from
end repeat
L -- {501, 502}
Once we know the uid numbers of the logged-in users, we