Der AppleScript-Befehl „delay“ funktioniert nicht, da zu Yosemite

Hinweis: Das Problem mit delay wurde in OS X 10.11 El Capitan behoben.

Seit dem Upgrade auf Yosemite funktionieren Applescripts, die Verzögerungen verwenden, nicht mehr . Wie kann ich das beheben?

Hier ist das einfachste Applescript der Welt, um ein einfaches Beispiel zu nennen:

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 

Dies sollte 30 Sekunden dauern. Wenn ich es im Skript-Editor (früher Applescript-Editor) ausführe, dauert der Vorgang 30 Sekunden. Wenn ich dieses Skript jedoch als App speichere, werden beim Starten der App die Verzögerungen ignoriert und die App benötigt einen Bruchteil einer Sekunde.

Wie kann ich Applescript zwingen, um einen bestimmten Betrag zu verzögern? Zeit, bevor Sie mit dem nächsten Schritt fortfahren? Ist das eine Yosemite-Panne? Gibt es eine zuverlässige Problemumgehung?

Kommentare

  • Dies funktioniert wie erwartet auf meinem Mac (10.10.1)
  • Jede Idee Was bewirkt, dass es bei mir nicht funktioniert? Zur Verdeutlichung: Es funktioniert im Skript-Editor. Wenn ich das Skript jedoch als App speichere und dann die App starte, werden die Verzögerungen ignoriert. ‚ ist das Seltsamste.
  • Ich habe das gleiche Problem am 10.10.3
  • An Apple gemeldet: openradar.me/21588747
  • Dieses Problem wurde in OS X 10.11 El Capitan behoben.

Antwort

Hinweis: Das Problem mit delay wurde in OS X 10.11 El Capitan behoben.

@ 2oh1, Sie haben die richtige Grundidee in Ihrer Antwort, aber hier ist eine vollständige und korrekte Antwort:

Die einzig vernünftige Möglichkeit, dies zu umgehen, besteht darin, „Verzögerung“ innerhalb einer Schleife aufzurufen, die sicherstellt, dass die gewünschte Dauer vergeht, bevor Sie fortfahren. Der beste Weg, dies zu tun, besteht darin, „Verzögerung“ mit einem benutzerdefinierten Handler zu überschreiben:

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 

Damit können Sie den Rest Ihres Skripts unverändert lassen und „delay“ normal verwenden, z. B.

delay 5 display alert "I like cake!" 

[HINWEIS: Normalerweise verwendet der benutzerdefinierte Handler zum Aufrufen die Option „Verzögerungsdauer fortsetzen“ die integrierte „Verzögerung“, aber ich habe festgestellt, dass dies zwar im Skript-Editor funktioniert, aber bei Verwendung in einem Applet einen Fehler zurückgibt („Verzögerung kann nicht fortgesetzt werden“. (-1708) ”). Ich habe dieses Problem umgangen, indem ich AppleScript direkt angewiesen habe, den Verzögerungsbefehl zu verarbeiten, anstatt „Weiter“ zu verwenden, um dorthin zu gelangen.]

Das Problem ist, dass delay Benutzer verarbeitet Eingabe, während das Skript angehalten wird, sodass Sie weiterhin auf Menüs oder Fenster klicken können, die von einem Applet angezeigt werden, und es gibt einen Fehler (behoben in 10.11), bei dem Benutzereingaben dazu führen, dass delay nicht auf das wartet volle Dauer, bevor die Skriptausführung fortgesetzt wird. Wenn Sie nicht mit dem Applet interagieren, funktioniert delay ordnungsgemäß.

Kommentare

  • Ist alles Dies ist ein Fehler, oder gibt es einen Grund, warum die Verzögerung bei Yosemite so funktioniert?
  • Es ist ein Fehler, dass die Verzögerung nicht ‚ verzögert.
  • Es ist ‚ so seltsam. Ich habe an einem Applescript herumgebastelt, das die Verzögerung in der letzten Nacht verwendet, und plötzlich funktionierte die Verzögerung wieder richtig. Ich nahm an, dass der Fehler behoben war Eine Stunde später, obwohl sich nichts geändert hatte, war der Fehler zurück. Ich ‚ bin wirklich verblüfft. Es spielt jedoch keine Rolle, ‚ Ich ‚ verwende eine Variable, um die Zeit und die Verzögerung bis zum Beispiel fünf Minuten später einzustellen, und ‚ funktioniert einwandfrei Also … Problem gelöst, aber das ‚ erklärt nicht, warum das Problem besteht. Interessant, interessant, interessant.
  • Weil Apple vermasselt hat. Apple Software ist viel weniger zuverlässig, seit sie OS X jährlich veröffentlicht. Ich vermisse die höheren OS X-Nebenversionen (wie 10.6.8), in denen das Betriebssystem absolut solide war. Sie haben nur ‚ keine solche Erfahrung mehr.
  • Wenn ‚ ein Fehler ist (dem stimme ich zu mit), warum ist ‚ nicht immer noch nicht behoben, frage ich mich. Hat hier jemand einen Radarbericht gemacht? Würden Sie dann bitte die ID posten? (oder / oder auch auf openradar.me posten)

Antwort

Während ich gegen dasselbe Problem kämpfte, stieß ich auf diese Antwort auf eine nicht so verwandte Frage und entschied sich, es zu versuchen, und es scheint Arbeite für mich.

Ersetze delay 5 durch do shell script "/bin/sleep 5" und erhalte das gleiche Ergebnis.

Kommentare

  • Danke fürs Teilen! Wie ich oben bereits sagte, kann ich ‚ dies nicht testen, da aus Gründen, die für mich keinen Sinn ergeben, Verzögerung 5 derzeit so funktioniert, wie es für mich sein sollte (ich habe es gerade getestet) es vor einem Moment wieder). Ich habe keine Ahnung, warum dies manchmal funktioniert und manchmal fehlschlägt.Es ist ‚ so seltsam. Am Ende habe ich eine Problemumgehung verwendet, bei der ich die aktuelle Zeit abrufe und als Variable festlege und dann das Skript anhalte, bis die Zeit variabel plus eine Minute ist (natürlich mit einer Verzögerung von 1 Minute). Es ist ‚ klobig, aber ‚ hat monatelang einwandfrei funktioniert, während eine einfache Verzögerung zeitweise aufgetreten ist. Ugh.
  • Ich verwende 10.10.5 und diese Lösung funktioniert nicht und sperrt das Skript auch für die Dauer des Ruhezustands.
  • @Greg: Wenn es das Skript für sperrt die Schlafdauer, dann funktioniert ‚. /bin/sleep wartet auf die Schlafdauer und kehrt erst nach Abschluss zurück. Im Gegensatz dazu verarbeitet der in AppleScript ‚ integrierte delay -Befehl Benutzereingabeereignisse, während das Skript angehalten wird. (Hier liegt der Fehler: Wenn eine Benutzertastatur eingegeben wird, setzt delay die Skriptausführung fort, bevor die Verzögerungsdauer abgelaufen ist.)

Antwort

Ich sage nicht, dass dies die beste Lösung ist, aber es scheint mein Problem gelöst zu haben. Anstatt eine einfache Verzögerung zu verwenden, die ignoriert wird Aus Gründen, die ich nicht verstehe, habe ich auf das Abrufen der Zeit und das Schleifen umgestellt, bis eine neue Zeit erreicht ist (es wird immer noch eine Verzögerung verwendet, aber es spielt keine Rolle, ob die Verzögerung ignoriert wird, da das Skript erst am Zeit ist erreicht).

# 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 

Ich möchte immer noch wissen, warum Verzögerungen ignoriert werden (oder dramatisch beschleunigt werden ?! ??), aber das wird Die Arbeit ist erledigt, ungeschickt wie sie ist.

Kommentare

  • Die “ Verzögerung “ ist nicht ‚ nicht “ beschleunigt “ , es ‚ wird unterbrochen. Während der Verzögerung befindet es sich in einer Schleife und prüft, ob Tastatureingabeereignisse vorhanden sind, damit es nach der Befehlsperiode suchen kann. Anscheinend verlässt es die Verzögerungsschleife fälschlicherweise, wenn Benutzereingaben erkannt werden.
  • Interessant! Ich ‚ stelle fest, dass ‚ ignoriert wird (beschleunigt? Unterbrochen?), Selbst wenn mein Mac im Leerlauf sitzt, aber ich nicht ‚ weiß nicht warum.
  • Sobald sich ein Benutzereingabeereignis in der Ereigniswarteschlange befindet, wird delay fortgesetzt unterbrochen werden, bis etwas die Ereignisse behandelt und aus der Warteschlange entfernt.

Antwort

Ich habe eine Arbeit gefunden. herum in einem deutschen Forumsbeitrag . Fügen Sie diese Zeilen oben in Ihr Skript ein:

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

Kommentare

  • I ‚ Ich habe Probleme beim Testen Ihrer Antwort, da die Verzögerung auf meinem Mac aus irgendeinem Grund derzeit wie erwartet funktioniert. Ich habe keine Idee warum. Ich ‚ führe 10.10.3 aus. Vielleicht hat Apple diesen Fehler behoben? Oder vielleicht ist ‚ nur ein zeitweiliges Problem, das ‚ derzeit keinen Einfluss auf meinen Mac hat. Pfui. Wie oben erwähnt, besteht meine Problemumgehung darin, dass Applescript die aktuelle Zeit abruft und dann bis zur aktuellen Zeit plus x verzögert.
  • Ich verwende auch 10.10.3 und sehe das Problem immer noch. Da nicht jeder das Problem sieht, ist es ‚ wahrscheinlich zeitweise oder im Zusammenhang mit Software von Drittanbietern oder bestimmten Voreinstellungen. Wer weiß. Übrigens hat Ihre Problemumgehung wahrscheinlich den Nachteil, dass die App während des Wartens weiterhin 100% CPU-Zeit verbraucht, während das richtige Verzögerungsverhalten darin besteht, die App für diese Dauer in den Ruhezustand zu versetzen und dadurch weniger Strom zu verbrauchen.
  • Ich verwende 10.10.5 und diese Lösung funktioniert nicht.
  • @ThomasTempelmann: Das Problem tritt auf, wenn Benutzereingaben vorliegen. Wenn Sie ‚ nicht klicken oder eingeben, während das Skript ausgeführt wird, wird der Fehler nicht ‚ ausgelöst.
  • Beachten Sie, dass diese Lösung bewirkt, dass die Anwendung für die Dauer des Schlafes tatsächlich einfriert. delay verarbeitet Benutzereingaben, während das Skript angehalten ist, sodass Sie beispielsweise weiterhin mit Menüs und Fenstern interagieren können.

Antwort

carzyj hatte meiner Meinung nach die beste Antwort, aber in Kombination mit der Methode von Chris Page erhalten Sie:

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

Sie können „Verzögerung“ bis „Verzögerung beenden“ auskommentieren, um zur ursprünglichen Verzögerung zurückzukehren.

Kommentare

  • I. Ich habe 10.10.5 ausgeführt und diese Lösung funktioniert nicht und sperrt das Skript für die Dauer des Ruhezustands.

Antwort

Dies ist eine Modifikation der @ chris-page-Lösung.

Es scheint ein Gleichgewicht zwischen Reaktionsfähigkeit und genauer Erfassung der Verzögerung zu sein.

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 

Anstatt Applescript anzuweisen, die Gesamtdauer zu verzögern, weisen wir es nur an, es um einen Bruchteil der Dauer zu verzögern. Wenn der Zeitraum kürzer ist als der, den Apple zulässt (1/60 Sekunde), setzen wir ihn einfach auf dieses Delta. Wir können zwar eine gewisse Reaktionsfähigkeit beibehalten und dennoch genau sein. Der Verdacht besteht darin, dass manchmal keine Verzögerung auftritt Arbeiten Sie so, dass die Wiederholungs-while-Schleife den Thread blockiert. In Erfolgsszenarien möchten wir jedoch, dass das Verzögerungsdelta kurz ist, damit der Prozess weiterhin unterbrochen werden kann.

Kommentare

  • Das Verkürzen der angeforderten Verzögerung ist nicht erforderlich und kann das Skript nur langsamer ausführen und während des Wartens mehr CPU verbrauchen. Meine Version ruft lediglich die Verzögerung auf, bis die gesamte gewünschte Dauer abgelaufen ist, sodass delay so viel wie möglich verzögern kann, bevor die Ausführung fortgesetzt wird.
  • Beachten Sie dies seit dieser Antwort wurde veröffentlicht, ich habe meinen Code aktualisiert, um delay endTime - (current date) anstelle von delay duration zu verwenden, wodurch sichergestellt wird, dass delay wird nicht ‚ t unterbrochen. ‚ pausiert das Skript nicht länger als die ursprünglich angeforderte Zeit Dies war möglicherweise das, was Sie mit dieser Antwort ansprechen wollten.

Antwort

Also, um es auszudrücken Ich glaube, Chris meint das alles so:

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 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.