9と10.1でのAppleScriptの違いは?

10.1でのAppleScriptについてですが、これについて、なかなか情報がないので困っております。
MacOS9時代につくったAppleScriptのアプリケーションが多数あるのですが、ダイアログを表示でして処理するもの、たとえば、
display dialog "このコンピュータを終了させますか?" buttons {"キャンセル", "再起動", "終了"} default button 3 with icon stop
set ANS_0 to button returned of result
if ANS_0 is "終了" then
tell application "Finder"
shut down
end tell
else if ANS_0 is "再起動" then
tell application "Finder"
restart
end tell
else if ANS_0 is "キャンセル" then
return
end if
というような、システム終了か再起動を選択できるだけの単純なものでも、ダイアログが文字化けしたり、ボタンをクリックしても正常に動かないなど、トラブルが多発します。また、充分検証していないのですが、複数のファイル名やフォルダ名を一括して変更するドロップレットもうまく作動しません。
 MacOS9にくらべ、MacOSXでは、AppleScriptに関してどのような変更がなされたのか、いままでのスクリプトはどのように書き変えるべきなのか、具体的な事例を扱ったサイトなり、書籍はどこかにないものでしょうか?

投稿日 2001/11/10 10:33

返信: 12

2001/11/10 22:45 Community User への返信

こんばんは
>ダイアログが文字化けしたり
アプリケーションとして保存した場合ですよね。
私はScript Editorに日本語アプリケーションとして保存する機能が実装されていないと考えています。
間違ってたらどうか指摘してください。
ですから、英語アプレットは日本語を表示させる事ができないと考えています。
そんな場合、二通りの対処をしています。
1、アプレットにdisplay dialogするのではなく、Finderにdisplay dialogする
Tsukahara, Akiraさんのスクリプトを勝手に使わせて頂きました。m(_ _)m
tell application "Finder"
activate
display dialog "このコンピュータを終了させますか?" buttons ツ
{"キャンセル", "再起動", "終了"} default button 3 with icon stop
set ANS_0 to button returned of result
if ANS_0 is "終了" then shut down
if ANS_0 is "再起動" then restart
end tell
とすればアプリケーションにしても文字化けしないと思います。
2、コンパイル済みスクリプトとして保存し、Script Menuから実行する。
でもドロップレットはScript Menuじゃ無理だし・・・。
私もMac OS X用のApple Script書籍をまだかまだかと期待してます。
AppleScriptリファレンス製作委員会がX版を出してくれることを願う。
# 最近、猛勉強してるのですが参照がいまいち苦手っす。

2001/11/10 23:03 Community User への返信

OSXではどうもダブルクリックによって開けるような、
アプリケーション形式で保存されたスクリプトは
それ単体では言語設定が自動的に英語になるらしく、
うまく実行できませんが、全て英語に書き換えておくことで
トラブルの量は格段に減ります。
ScriptMenuなるAppleScriptやperl等を
メニューバーから実行できるようになるツールを入れ、
そこから呼び出した場合や、script editorなどの
他のプログラムから呼び出す場合は日本語が有効に機能します。
この点を考慮して、例えば以下のように、
2バイト対応か否かに左右されないスクリプトを組んでおけば
将来の仕様変更に伴う改造も比較的楽に行えるでしょう。
----
property LANGUAGE : "En"
script localized_string
on _CONFIRM_BEEP()
if LANGUAGE is "Ja" then
return "ビープします?"
else
return "Beep?"
end if
end _CONFIRM_BEEP
on _CANCEL()
if LANGUAGE is "Ja" then
return "キャンセル"
else
return "cancel"
end if
end _CANCEL
on _OK()
return "OK"
end _OK
end script
on run
set LANGUAGE to "En"
try
if character 3 of "日本語" is "語" then set LANGUAGE to "Ja"
end try

set buttonsList to {_CANCEL() of localized_string, _OK() of localized_string}
get button returned of (display dialog (_CONFIRM_BEEP() of localized_string) buttons buttonsList default button 1)
if result is _OK() of localized_string then
beep 2
end if
end run

2001/11/12 21:13 Community User への返信

ご返事ありがとうございます。
編集してくださったスクリプト、早速実行してみました。確かに文字化けは治りました。なるほど!
ただ、これらのボタンを押しても、スクリプトは正常に作動せず、終了も再起動もしないまま、例の丸いポインターがくるくる回っているばかりです。どうも、「Shut down」「restart」の命令自体も、書き方を工夫しなくてはならないようで・・。
>私もMac OS X用のApple Script書籍をまだかまだかと期待してます。
>AppleScriptリファレンス製作委員会がX版を出してくれることを願う。
全く同感です。AppleScripは、Windowsに対する数少ないMacの優位点だけに、このような非互換性が発生し、それについて、日本のアップルがしっかりサポートしていないというのは納得できません。10.1のヘルプもAppleScripに関する説明が、9時代に比べてえらく貧弱になってますし。英語用のスクリプトをおまけに付ければいいってもんじゃない。

2001/11/12 21:19 Community User への返信

早速のご返事、ありがとうございます。
ところで、紹介してくださったスクリプトは、どこに、どのように組み込めばよろしいのでしょうか?それぞれのスクリプトの冒頭に、ということでしょうか?なんだかひどく基本的な質問で恐縮です。

2001/11/12 21:58 Community User への返信

こんばんは
>どうも、「Shut down」「restart」の命令自体も、書き方を工夫しなくてはならないようで・・。
本当だ。実際に自分で動作確認してませんでした。すみません。
どうやら、ボタンが動作していないのではなく、仰るとおり、
「shut down」と「restart」が正常に動かないみたいですね。
tell app "Finder" to restart または
tell app "Finder" to shut down
としても、同様にクルクルになっちゃいます。
しかも、アプレットを強制終了するとログアウトするだけだし。
Script Editer上からやってみても同じ。
「sleep」はちゃんと動くみたいです。
Finderの用語説明にはバッチリ「restart」と「shut down」が載ってるのにね。
ぼちぼちフィードバックしときます。
貴重な情報ありがとうございました。m(_ _)m

2001/11/13 04:55 Community User への返信

"----"以下をそのままScriptWditorで
単一のドキュメントにコピーペーストすればOKです
これは、日本語を適切に処理できるかどうかを自動的に判断し、
そうであるかどうかで表示するメッセージを
調整して表示すると言う一例です。
{再起動,システム終了,キャンセル}でやると下のような感じになります。
----
property LANGUAGE : "En"
script localized_string
on _CONFIRM_SHUTDOWN()
if LANGUAGE is "Ja" then
return "このコンピュータを終了させますか?"
else
return "Sure you want shut down this computer?"
end if
end _CONFIRM_SHUTDOWN
on _SHUTDOWN()
if LANGUAGE is "Ja" then
return "システム終了"
else
return "Shut down"
end if
end _SHUTDOWN
on _CANCEL()
if LANGUAGE is "Ja" then
return "キャンセル"
else
return "Cancel"
end if
end _CANCEL
on _RESTART()
if LANGUAGE is "Ja" then
return "再起動"
else
return "Restart"
end if
end _RESTART
end script
on run
set LANGUAGE to "En"
tell application "Finder"
try
if character 3 of "日本語" is "語" then set LANGUAGE to "Ja"
end try
set buttonsList to {_CANCEL() of localized_string, _RESTART() of localized_string, _SHUTDOWN() of localized_string}
activate
set ans to button returned of (display dialog (_CONFIRM_SHUTDOWN() of localized_string) buttons buttonsList default button 1 with icon 0)
ignoring application responses --アプリの応答を無視して
if ans is _RESTART() of localized_string then restart
if ans is _SHUTDOWN() of localized_string then shut down
end ignoring
end tell
end run
----
それから、スクリプト内で文字列を同じかどうかを評価するような時は、
あらかじめ変数に保存しておくのが普通です。
うっかり"再起動"と"再越動"を比べてしまってて
うまく動かないなんて**げてますからね。
(変数のスペルミスはそこでエラーが出るからすぐ気付く)

2001/11/13 19:09 Community User への返信

詳細なご教示、大変助かります。
ところで、教えていただいたスクリプトをScriptEditorに読込ませて、構文確認させると、3行目の冒頭の空白が選択されて、エラーが出ます。
「構文エラー
”end of line”と書くべきところに
”unknown token”と書かれています。」
これは、・・?

2001/11/13 21:07 Community User への返信

テキストファイルにでもして別ページへ載せた方が良かったでしょうかね、
それは「"end of line(改行)"すべきところに"unknown token"(不明な単語区切り)が存在する」エラーで、
ブラウザからコピー&ペーストしたときなどにたまにある現象です。
行の末尾からウインドウ右端までの空白が選択された場合は
改行コードが異常ですのでそのまま選択解除せずリターンキーを、
行先頭から1文字目までの空白の場合、全角のスペースなどが入っている場合ですので
同様にスペースキーで半角にしてあげて下さい。
こういうときはミミカキエディットの置換を使うとすごく楽なんですけどね。
とりあえず、うちではちゃんとシステム終了も再起動も、
呼び出し方に関わらずきちんと機能してますので。

2001/11/13 22:37 Community User への返信

こんばんは
thumbさん、教えて下さい。
>とりあえず、うちではちゃんとシステム終了も再起動も、
>呼び出し方に関わらずきちんと機能してますので
これは、thumbさんの書かれているスクリプトの場合において、呼び出し方に関わらず
きちんと機能しているという意味でしょうか。
それとも、OS 9.x以前の時に有効だった書き方でもきちんと機能しているという意味でしょうか。
tell app "Finder" to restart
と書いてもきちんと機能されているのでしょうか。
thumbさんの書かれているスクリプトを拝見させていただくと、
下から6行目の
ignoring application responses
〜〜〜
〜〜〜
end ignoring
が鍵だと思います。上でTsukahara, Akiraさんが書かれているスクリプトに
追加しますと正常に機能するようになりました。
応答を待たずに先へ進むStatementとの事ですが、なぜこのように書かなければ正常に機能しないのでしょうか。
tell app "Finder" to restart をアプレットにして実行してみると、
クルクルが続き、「アプリケーション"XXXXXX"の終了に失敗した為、時間切れで・・・・」
とダイアログが出ます。
なぜこの時、アプレット"XXXXXX"の終了に失敗するのでしょうか。
よろしくお願いします。

2001/11/14 20:16 Community User への返信

thumb様、毎度の丁寧なご教示、恐れ入ります。
正常に動くようになりました。ありがとうございます。
それにしても・・・
たかが、終了のダイアログを作るのに、こんな長文のスクリプトになるとは・・なんか釈然としないものがありますね。MacOSXのスクリプト環境は、以前に比べ大幅に劣悪なものになっているとしか思えない・・スクリプトばかりでなく、アプリケーション間のコピー・アンド・ペーストでも文字化けが頻発するなど、人間の言語の基本的な取扱いでもたつくなんて、非常識にもほどがある。・・やっぱ、使いものになりませんね、OS X。少なくとも日本語環境では。

2001/11/14 22:18 Community User への返信

>「呼び出し方に関わらず・・・」とは?
ここで書いた例文はAppleScript1.1から利用可能な構文のみで
構成されており、それは漢字Talk7.5.6くらいから
ダブルクリックでの起動もしくはスクリプト編集プログラムなど
外部プログラムからの間接的な実行であるなど、
呼び出し方を問わず動作するスクリプトであり、
かつOSXでの日本語を正常に処理できないと言う局面にも
対応しているものであると言うことです。
>なぜ"ignoring"ブロックがないといけないのか?
これは、AppleScriptでは一つの文を実行するのに、
それを実行するプロセスがアクティブでない場合は
デフォルトでは1分以上結果を待つことができないという仕様があるからです。
たとえば今回のようにシステム終了の場合、
もし他のアプリケーションで未保存の書類があった場合、
それを保存するかどうかを尋ねてくるはずですが、
このとき1分以内に保存場所を指定できると言う保証は無く、
かつ保存ダイアログが出ている間は、命令を送った相手である
Finderはアクティブな状態ではありません。
ignoringブロックは、このような、いつ実行結果を
受け取れるかどうか分からないような命令を送る場合のルールみたいなものです。
未保存の書類が無くてもこれがないと動かないのは僕にも分からないのですが、
おそらくはOSXでプロセスの管理方法が変化したことで、
全てのプロセスを終了させる意味を持つrestartやshutdownを
応答待ちであるアプリケーション、つまり命令を送っているスクリプト自身が、
終了せよと言う命令に応答できない状態にあることが原因と思われます。
それと、「デフォルトでは一分以内」と先に書きましたが、
これは「with timeout of 10 seconds・・・end timeout」を使って
自分で特定のブロックにタイムアウトを設定することができます。
ネットワーク経由でデータをやり取りするスクリプトを作成する場合に大変役立ちます。
他にも実行に時間がかかる処理や、10分ごとにメールチェックみたいな
長期的に稼働するスクリプトを作るのに便利な
idleハンドラなんて言うのもあります。

2001/11/15 01:56 Community User への返信

thumbさん、ありがとうございます。
>おそらくはOSXでプロセスの管理方法が変化したことで、
>全てのプロセスを終了させる意味を持つrestartやshutdownを
>応答待ちであるアプリケーション、つまり命令を送っているスクリプト自身が、
>終了せよと言う命令に応答できない状態にあることが原因と思われます。
応答待ちって何の応答を待ってるんでしょうか。
shut downやrestartってFinderはアプレットに何も返さないはず。
何も返さないのでスクリプトは終了するはず。
でも何か返そうとしてるから応答待ち?になってて終了できない?
結局のところ、再起動させる為には
ignoring application responses
 tell application "Finder" to restart
end ignoring
と書かなければ機能しない。ということは十分フィードバック事項ですね。
このスレッドが無ければ知らないままでした。
ありがとうございました。

このスレッドはシステム、またはAppleコミュニティチームによってロックされました。 問題解決の参考になる情報であれば、どの投稿にでも投票いただけます。またコミュニティで他の回答を検索することもできます。

9と10.1でのAppleScriptの違いは?

Apple サポートコミュニティへようこそ
Apple ユーザ同士でお使いの製品について助け合うフォーラムです。Apple Account を使ってご参加ください。