MacScripterのフォーラムでeppcについての質問があったので回答していました。eppcを用いて、ネットワーク上の他のMacを操作する件についての話でした。
eppcは、Remote AppleEventのプロトコル表記であり、自分のマシン上のアプリケーションだと、
application "Finder"
と表記しますが、他のMac上のアプリケーションだと、
application "Finder" of machine "eppc://user:password@machineName.local"
という表記になります。パスワードを書いておかないとダイアログで問い合わせが行われるので、書かなくてもいいです(パスワードが丸裸で書いてあるのは不用心なので、テスト時以外はおすすめしません)。
自分の認識では、ネットワーク上の他のマシンの操作については、
のような認識でした。この認識は間違っているわけではなく、リモートのアプリケーション操作はリモート側のアプレットに行わせるようにして、自分からはリモート側のアプレットのハンドラを呼び出すのがリモートアプリケーション操作の基本的な「作法」です。
GUIアプリケーションを直接操作するのは無理だけど、AppleScriptアプレットを常駐させておいて、アプレットのハンドラを呼び出すことで、各リモートマシン上のアプリケーションを操作できる、と。
で、これが他のメンバーのコメントで(リモートアプリケーションのダイレクト呼び出しは)「macOS 10.15でもできるぞ」という話が出てきて、腰を抜かしました。現状の自分のマシン環境(古いのばっかりですが)で検証してみたところ、たしかに(若干の癖はありますが)、GUIアプリケーションを直接操作できて驚きました(セキュリティ上の制約がいろいろあるので、ローカルでできることすべてがリモートアプリケーションに直接司令できるわけではありません)。
▲テストに用いたMac OS X 10.6.8環境
▲テストに用いたMac OS X 10.7.5環境
▲テストに用いたMac OS X 10.13.6環境
Mac OS X 10.6からmacOS 10.12あたり(厳密には確認できていない)の環境では、明確にリモートAppleEventに制約が加わっていました。
ところが、macOS 10.13あたり(10.12かも。このあたり未確認)から、eppcでGUIアプリケーションの操作ができることが確認できました。
macOS Version |
Direct eppc to GUI Apps |
10.0 |
(No AppleScript Env) |
10.1 |
Works???? |
10.2 |
Works |
10.3 |
Works |
10.4 |
Works |
10.5 |
(???) |
10.6 |
Not Work |
10.7 |
Not Work |
10.8 |
Not Work |
10.9 |
Not Work |
10.1 |
Not Work |
10.11 |
Not Work |
10.12 |
(??? Maybe not work) |
10.13 |
Works |
10.14 |
Works |
10.15 |
Works |
eppcのポート
eppcがTCP/IPのどこのポート番号を用いているかは、/etc/servicesを見ると書いてあります。
eppc 3031/udp # Remote AppleEvents/PPC Toolbox
eppc 3031/tcp # Remote AppleEvents/PPC Toolbox
なので、VPN接続時にこれらのポートが開いていれば、相手側のマシンをAppleScriptで遠隔操作できることになります(実際には、ファイル共有とかいろいろその他の付随するポートを開けておく必要があるわけですが)。
リモート操作の傾向
ただし、ローカルマシン上のアプリケーションを操作するのと比較して、いくつかの挙動の違いも見られます。
(1)アプリケーションの直接的な起動が効かない
各GUIアプリケーションに「activate」とか「launch」コマンドを送っても無視されます。リモートマシン上でいったんアプリケーションが起動した後に「activate」で最前面に持ってくることは可能ですが、起動していない状態でactivateを実行しても、起動は行われません。
AppleScript名:他のマシン上でSafariを起動 |
set RemoteMachine to "eppc://me@MacMini2014.local"
using terms from application "Finder" tell application "Finder" of machine RemoteMachine open application file id "com.apple.Safari" end tell end using terms from |
★Click Here to Open This Script
|
Finder経由でBundle IDを指定して「application fileをオープンする」という指定であれば、たしかにアプリケーションが起動します。
(2)System Eventsの操作に難あり
面白くなっていろいろリモートアプリケーションを操作していてわかってきたのですが、初期状態だとSystem Eventsが起動していない状態です。いえ、ローカルでもSystem Eventsは常時起動してはいないんでしょうけれど、命令を発行すると自動で起動されます。
この自動起動とか明示的に指定して起動といった操作が受け付けられないので、Finder経由で間接的にapplication fileのオープンというかたちでSystem Eventsの起動を行い、処理を依頼します。
このリモートマシン上のSystem Eventsはしばらく処理が行われないと自動で終了するようなので、何かまとまった処理をSystem Eventsに行わせる前には明示的に起動を司令しておくべきなんでしょう。
AppleScript名:他のマシン上のSystem Eventsを起動する |
set RemoteMachine to "eppc://me@MacMini2014.local"
using terms from application "Finder" tell application "Finder" of machine RemoteMachine open application file id "com.apple.SystemEvents" end tell end using terms from
|
★Click Here to Open This Script
|
(3)けっこう動く
GUIアプリケーションの代表としてSafariを実際に操作してみたところ、
Safariのバージョン名の取得、できました。
AppleScript名:他のマシン上で起動しているアプリケーションのバージョンを取得 |
set RemoteMachine to "eppc://me@MacMini2014.local"
using terms from application "Safari" tell application "Safari" of machine RemoteMachine version end tell end using terms from |
★Click Here to Open This Script
|
Safariの新規ウィンドウの作成、できました。
AppleScript名:他のマシン上で起動しているSafariで新規ウィンドウ作成 |
set RemoteMachine to "eppc://me@MacMini2014.local"
using terms from application "Safari" tell application "Safari" of machine RemoteMachine make new document end tell end using terms from
|
★Click Here to Open This Script
|
SafariのウィンドウのURLの取得、できました。
AppleScript名:他のマシン上で起動しているSafariの最前面のウィンドウのURLを取得 |
set RemoteMachine to "eppc://me@MacMini2014.local"
using terms from application "Safari" tell application "Safari" of machine RemoteMachine set aURL to URL of front document end tell end using terms from |
★Click Here to Open This Script
|
SafariのウィンドウのURLの書き換え、できました。
AppleScript名:他のマシン上で起動しているSafariのウィンドウのURLを書き換える |
set RemoteMachine to "eppc://me@MacMini2014.local"
using terms from application "Safari" tell application "Safari" of machine RemoteMachine set URL of document 1 to "http://piyocast.com/as/" end tell end using terms from |
★Click Here to Open This Script
|
Safariの最前面のウィンドウの内容をメールに転送、できました。
AppleScript名:他のマシン上で起動しているSafariの最前面の内容をメール |
set RemoteMachine to "eppc://me@MacMini2014.local"
using terms from application "Safari" tell application "Safari" of machine RemoteMachine make new document set URL of front document to "http://www.apple.com" delay 3 –wait for page loading email contents of front document end tell end using terms from
|
★Click Here to Open This Script
|
Safariのページローディング検出はいろいろ蓄積されているノウハウもありますが、do javascriptコマンドが問題なく動くレベルまで信用できるのかわからなかったので、delayで単純に時間待ちしています。
実際に動かしてみて、自分がビビるぐらいeppcでリモートアプリケーションの操作ができてしまいました。SIPだとかアプリケーション権限だとかでセキュリティ機能でがんじがらめにされている今日このごろですが、eppc経由でリモートマシン上のアプリケーション操作が緩和されている事実にビビりました。
これはおそらくですが、Xcode上のリモートデバッグとか、そういうあたりの機能の実装時に機能がeppcまわりの機能が再実装されたかコメントアウトしていた箇所が復活したかという話に見えます。