Edited at

JXAの「Error: A privilege violation occurred」の回避

More than 3 years have passed since last update.

JXAでアプリケーションを指定してStandard Additionsのメソッドを使おうとすると頻繁に以下のエラーが出る。

var finder = Application("Finder");

finder.includeStandardAdditions = true;
finder.doShellScript("date");
//!! Error on line 1: Error: A privilege violation occurred.

この場合currentApplicationを使えばたぶん大体いける。

var app = Application.currentApplication();

app.includeStandardAdditions = true;
app.doShellScript("date");
//=> "2015年 2月25日 水曜日 17時16分28秒 JST"

currentApplicationはスクリプトを実行しているアプリケーションを取得するメソッド。

Script Editorから実行していればScript Editor。

Terminalから実行していればTerminal...じゃなくてosascriptコマンド。

Terminalが直接実行してるわけじゃないので。

他にも、例えば

CotEditorはユーザーが作ったスクリプトを利用できる。

そこで実行した場合のcurrentApplicationはCot Editor。


osascriptを参照した際のwarning


warning: failed to get scripting definition from /usr/bin/osascript; it may not be scriptable.


と毎回出るけど「osascriptには.sdefファイルが無いから、スクリプトで操作できないと思うよ」ってだけ。

osascript自体じゃなくStandard Additionsのメソッドを使うだけだから問題無し。のはず。

osascriptの参照から名前を得ようとして.name()とかやったらエラー出るので注意。

ていうかこれ不安になるだけだから表示しないでほしい。いややっぱ必要か。


スクリプトメニューから実行した場合のcurrentApplication

Script Editorみたいな分かり易いものならいいけど、スクリプトメニューから実行した場合は何が呼ばれるのか。

currentApplicationは多用するから、得体の知れないまま使うとモヤモヤする。

AppleScriptと違って、明示的にStandard Additionsを有効にしないと駄目だし気になったので調べた。


スクリプトメニューについて

スクリプトエディタの設定からスクリプトメニューを有効にするとメニューにアイコンが追加される。

スクリプトを~/Library/Scripts/に入れるとそのメニューに表示される。

コンパイル済みスクリプト(.scpt)にすればいつでもどこでもワンクリックで実行できる。

menu.jpg

ちなみにScript Editorを経由しないでも設定変更可能。

var app = Application("AppleScript Utility");

// 確認
app.scriptMenuEnabled();
//=> true / false

// 有効にする
app.scriptMenuEnabled = true;


スクリプトメニューの「currentApplication」

これを調べるスクリプトをJXAで書くと難しい。

ていうか結局、分からなかった。

AppleScriptだと簡単だった。


where_is_current_app.scpt

display dialog (path to current application)'s POSIX path


Script Editorで実行した場合。

editor.jpg

/Applications/Utilities/Script Editor.app/

スクリプトメニューから実行した場合。

menu_.jpg

/usr/bin/osascript

普通にosascriptだった。


蛇足

予想では専用のアプリケーションがあるのか、最前面のアプリが使われるのか、Finderなのかとか考えてた。

昔はこれだったらしい。今は存在しない。(参考:MacWiki)

/System/Library/CoreServices/AppleScript Runner.app


スクリプトメニューでエラーが発生した場合

何も起こらない。何も通知されない。

途中で単に実行が停止されるので注意。

ちゃんと try...catch すればだいじょぶ。

コンソール.appにエラーのヒントが残ってるかもしれない。

スクリーンショット 2015-02-25 18.55.29.png


蛇足2

上に書いたけどcurrentApplicationの名前はAppleScriptで一行で得ることが出来た。

JXAで何とかしようとしてた(けど出来なかった)コードをここで供養する。

var app = Application.currentApplication();

app.includeStandardAdditions = true;

var str = Automation.getDisplayString(app);

// これじゃたぶん意味ない。(osascriptで実行してるじゃん)
//msg = app.doShellScript('osascript -l JavaScript -e "Application.currentApplication()" 2>&1 1> /dev/null | cat');
//str += "\n" + msg;

try { // try..catchしとかないとエラー出たら無言でアプレット消える
str += "\n\nproperties: " + Automation.getDisplayString(Object.getOwnPropertyNames(app));

str += "\nname: " + app.name(); //osascriptから.name()とか呼んだらエラー出る
str += "\n\n" + JSON.stringify(app.properties(), null, " ");

} catch(e){
str += "\n\n" + e.toString();
}

app.displayDialog(str);

Script Editorで実行した場合のダイアログ。

Application.currentApplication()

properties: ["__private__"]
name: Script Editor

{
"frontmost": true,
"class": "application",
"name": "Script Editor",
"version": "2.7"
}

スクリプトメニューから実行した場合のダイアログ。

Application.currentApplication()

properties: ["__private__"]

Error: Message not understood.

JXAのStandard AddisionsにもpathToはある。

けどcurrent applicationを文字列で渡したりcurrentApplicationをそのまま渡してもパスを得られなかった。

JXAでパスを得る方法があったなら知ってる方は教えて下さい。


参考