ヨセミテに切り替えてからAppleScriptの「遅延」コマンドが機能しない


10

注:の問題delayはOS X 10.11 El Capitanで修正されました。

ヨセミテにアップグレードしてから、遅延を使用するApplescriptが機能しなくなりました。どうすれば修正できますか?

簡単な例として、世界で最も単純なApplescriptを以下に示します。

set volume output volume 0
delay 5
set volume output volume 20
delay 5
set volume output volume 0
delay 5
set volume output volume 20
delay 5
set volume output volume 0
delay 5
set volume output volume 20
delay 5
set volume output volume 0

完了するまで30秒かかります。スクリプトエディター(以前のApplescriptエディター)で実行すると、完了までに30秒かかります。しかし、このスクリプトをアプリとして保存した場合、アプリを起動すると、遅延は無視され、アプリの完了までに数分の1秒かかります。

Applescriptに次のステップに進む前に指定した時間だけ遅延させるにはどうすればよいですか?これはヨセミテの不具合ですか?信頼できる回避策はありますか?


これは私のMac(10.10.1)で期待どおりに動作します
markhunte

それが私の仕事をしない原因は何ですか?明確にするために、スクリプトエディターでは機能しますが、スクリプトをアプリとして保存してからアプリを起動すると、遅延は無視されます。それは最も奇妙なことです。
2oh1

10.10.3でも同じ問題があります
Thomas Tempelmann


1
この問題はOS X 10.11 El Capitanで修正されました。
Chris Page

回答:


7

注:の問題delayはOS X 10.11 El Capitanで修正されました。

@ 2oh1、あなたはあなたの答えに正しい基本的な考えを持っていますが、ここに完全で正しい答えがあります:

これを回避するための唯一の妥当な方法は、ループの中で「遅延」を呼び出して、続行する前に必要な期間が経過することを保証することです。これを行う最善の方法は、カスタムハンドラーで「遅延」をオーバーライドすることです。

on delay duration
  set endTime to (current date) + duration
  repeat while (current date) is less than endTime
    tell AppleScript to delay endTime - (current date)
  end repeat
end delay

これにより、残りのスクリプトを変更せずにそのままにして、通常は「遅延」を使用できます。たとえば、

delay 5
display alert "I like cake!"

[注:通常、カスタムハンドラーは "continue delay duration"を使用して組み込みの "delay"を呼び出しますが、これはスクリプトエディター内で機能しますが、アプレット内で使用するとエラーを返すことがわかりました( "Can ' t継続遅延(-1708)」)。私は、「続行」を使用する代わりに遅延コマンドを処理するようAppleScriptに直接指示することで、この問題を回避しました。]

問題はdelay、スクリプトの一時停止中にユーザー入力を処理するため、アプレットによって表示されたメニューまたはウィンドウをクリックすることができ、ユーザー入力がdelayスクリプトの実行を再開する前に完全な期間待機しないというバグがあります(10.11で修正)。。アプレットと対話しない場合、delay正しく動作します。


これはすべてバグですか、それともヨセミテで遅延がこのように機能している理由がありますか?
2oh1 2015

遅延が遅延していないのはバグです。
クリスペイジ

奇妙です。私は先日の遅延を使用するアップルスクリプトをいじっていましたが、突然、遅延は再び正しく機能していました。バグが修正されたと思います。1時間後、何も変わっていないにもかかわらず、バグが戻ってきました。私は本当に困惑しています。それは問題ではありません。変数を使用して時間を設定し、(たとえば)5分後まで遅延させますが、それは完全に機能しています。だから...問題は解決しましたが、問題が存在する理由は説明されていません。面白い、面白い、面白い。
2oh1 2015年

1
アップルが間違えたので。Appleソフトウェアは、OS Xを毎年リリースし始めたため、信頼性がはるかに低くなっています。OSが非常に安定していた、より高いOS Xマイナーバージョン(10.6.8など)がありません。そのような経験はもう得られません。
William T Froggard

それがバグである(同意する)場合、なぜこれがまだ修正されていないのでしょうか。ここで誰かがレーダー報告をしましたか?次に、そのIDを投稿してください。(またはopenradar.meにも投稿)
Thomas Tempelmann

5

この同じ問題と戦いながら、あまり関係のない質問この答えを見つけ、それを試すことにしましたが、私にはうまくいくようです。

単純に置き換えるdelay 5do shell script "/bin/sleep 5"、同じ結果を得ます。


共有してくれてありがとう!先に述べたように、私はこれをテストすることができません。理由がわからないので、遅延5は今のところ正常に機能しています(少し前にもう一度テストしました)。なぜこれが時々機能し、時々失敗するのか私にはわかりません。奇妙です。最終的には、現在の時刻を取得して変数として設定する回避策を使用し、その後、時刻が変数に1分プラスするまでスクリプトを一時停止しました(明らかに1分の遅延の場合)。それは不格好ですが、何ヶ月も問題なく動作しましたが、単純な遅延は断続的でした。ああ。
2oh1 2015

10.10.5を実行していますが、このソリューションは機能せず、スリープの間スクリプトをロックします
Greg

@Greg:スリープ期間中に「スクリプトをロック」する場合、機能しています。/bin/sleepスリープ期間を待機し、完了するまで戻りません。対照的に、AppleScriptの組み込みdelayコマンドは、スクリプトが一時停止しているときにユーザー入力イベントを処理します。(バグが存在する場所:ユーザーのキーボード入力がある場合delay、遅延期間が完了する前にスクリプトの実行を続行します。)
Chris Page

3

これが最善の解決策であるとは言いませんが、私の問題は解決したようです。理解できない理由で無視されている単純な遅延を使用する代わりに、時間を取得して新しい時間に到達するまでループするように切り替えました(それでも遅延が使用されますが、無視しても問題ありません)スクリプトが時間に達するまで続行されないための遅延)。

# Pause for five minutes
set GetTheTime to current date
set NewTime to GetTheTime + (5 * minutes)
repeat while (current date) is less than NewTime
    delay 60
end repeat

なぜ遅延が無視されているのか(または劇的にスピードアップしているのか?!???)まだ知りたくありませんが、これで仕事が完了します。


「遅延」コマンドは「スピードアップ」されておらず、中断されています。遅延している間、それはループ内にあり、キーボード入力イベントがあるかどうかをチェックして、コマンド期間をチェックできるようにします。どうやら、ユーザー入力が検出されると、遅延ループを誤って終了します。
クリスペイジ

面白い!Macがアイドル状態でも無視されている(スピードアップ?中断されている?)とわかりましたが、なぜなのかわかりません。
2oh1 2015年

ユーザー入力イベントがイベントキューにdelay入ると、何かがイベントを処理してキューから削除するまで中断され続けます。
Chris Page

2

ドイツのフォーラム投稿で回避を見つけました。次の行をスクリプトの先頭に追加します。

use framework "Foundation"
use scripting additions
current application's NSThread's sleepForTimeInterval:1

私のMacでは現在、何らかの理由で遅延が期待どおりに機能しているため、回答をテストできません。なぜかわかりません。10.10.3を実行しています。おそらくAppleがこのバグを修正したのでしょうか?あるいは、現時点でMacに影響を与えていないのは、断続的な問題だけかもしれません。ああ。上記で述べたように、私の回避策は、Applescriptに現在の時刻を取得させ、現在の時刻にxを加えるまで遅延させることです。
2oh1 2015年

10.10.3も実行していますが、まだ問題が発生します。誰もが問題を目にするわけではないので、それはおそらく断続的であるか、サードパーティのソフトウェアまたは特定の設定に関連しています。知るか。ところで、回避策にはおそらく、アプリが待機中にCPU時間を100%使用し続けるという欠点がありますが、適切な遅延動作は、アプリをその期間スリープ状態にして、消費電力を少なくすることです。
Thomas Tempelmann 2015年

10.10.5を実行していますが、このソリューションは機能しません。
グレッグ

@ThomasTempelmann:この問題は、ユーザー入力がある場合に発生します。スクリプトの実行中にクリックまたは入力しないと、バグは発生しません。
Chris Page

このソリューションでは、アプリケーションがスリープ中に実際にフリーズすることに注意してください。delayスクリプトの一時停止中にユーザー入力を処理するため、たとえばメニューやウィンドウを操作できます。
Chris Page

0

carzyjは私が最良の答えだと思うものでしたが、Chris Pageの方法と組み合わせると、次のようになります。

on delay duration
  do shell script "/bin/sleep " & duration
end delay

「遅延」から「遅延終了」までコメントアウトして、元の遅延に戻すことができます。


これを見る前に、同様のコード変更も行いました。10.10.5を実行していますが、このソリューションは機能せず、スリープ中はスクリプトがロックされます。
グレッグ

0

これは@ chris-pageソリューションの変更です

それは、応答性と正確に遅延を捕捉することの間のバランスのようです。

on delay duration
    set endTime to (current date) + duration
    repeat while (current date) is less than endTime
        set delta to duration / 100
        if duration < 0.2 then
            set delta to 0.2
        end if
        tell AppleScript to delay delta
    end repeat
end delay

ただし、全体の期間にわたって遅延するようにApplescriptに指示する代わりに、期間の端数期間だけ遅延するように指示します。期間がアップルの許容範囲(1/60秒)未満の場合は、そのデルタに設定します。ある程度の応答性を維持しながら、まだ正確であること。疑わしいのは、遅延が機能しない場合があるため、繰り返しwhileループがスレッドをロックしたままにすることですが、成功シナリオでは、プロセスを中断できるように遅延デルタを短くする必要があります。


要求された遅延を短くすることは不要であり、待機中にスクリプトの実行を遅くし、より多くのCPUを消費するだけです。私のバージョンでは、希望する期間全体が経過するdelayまでdelayを呼び出すだけで、実行を継続する前に可能な限り遅延させることができます。
Chris Page

この回答が投稿されたので、私が使用して自分のコードを更新することを注意delay endTime - (current date)の代わりにdelay durationあればことを保証し、delay しない中断を取得、それはもはや元々要求された時間よりも、スクリプトを一時停止していないだろう、あなたがしようとしていたものであったかもしれませんこの答えのアドレス。
Chris Page

0

だから、すべてをまとめると、クリスはこれを意味すると信じています:

on delay duration
   set endTime to (current date) + duration
   repeat while (current date) is less than endTime
      tell AppleScript to delay endTime - (current date)
   end repeat
end delay
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.