Remarque: Le problème avec delay
a été résolu dans OS X 10.11 El Capitan.
Depuis que je suis passé à Yosemite, les scripts Applescripts qui utilisent des retards ont cessé de fonctionner . Comment puis-je résoudre ce problème?
Voici lApplescript le plus simple au monde, pour un exemple simple:
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
Cela devrait prendre 30 secondes. Si je lexécute dans Script Editor (anciennement Applescript Editor), cela prend 30 secondes. Mais si jenregistre ce script en tant quapplication, lorsque je lance lapplication, les retards sont ignorés et lapplication prend une fraction de seconde pour se terminer.
Comment puis-je forcer Applescript à retarder dun montant spécifié du temps avant de passer à létape suivante? Est-ce un problème de Yosemite? Existe-t-il une solution de contournement fiable?
Commentaires
- Cela fonctionne comme prévu sur mon Mac (10.10.1)
- Toute idée quest-ce qui fait quil ne fonctionne pas sur le mien? Pour clarifier: cela fonctionne dans Script Editor, mais si jenregistre le script en tant quapplication puis que je lance lapplication, les retards sont ignorés. Cest ‘ la chose la plus étrange.
- Jai le même problème le 10.10.3
- Rapporté à Apple: openradar.me/21588747
- Ce problème a été résolu dans OS X 10.11 El Capitan.
Réponse
Remarque: Le problème avec delay
a été corrigé dans OS X 10.11 El Capitan.
@ 2oh1, vous avez la bonne idée de base dans votre réponse, mais voici » une réponse complète et correcte:
La seule façon raisonnable de contourner ce problème est dappeler « delay » dans une boucle qui garantit que la durée souhaitée sécoule avant de continuer. La meilleure façon de faire est de remplacer « delay » avec un gestionnaire personnalisé:
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
Cela vous permet de laisser le reste de votre script inchangé et vous pouvez utiliser « delay » normalement, par exemple,
delay 5 display alert "I like cake!"
[NOTE: Normalement, le gestionnaire personnalisé utilisera « continue delay duration » pour appeler le « délai » intégré, mais jai trouvé que, bien que cela fonctionne dans léditeur de script, il renvoie une erreur lorsquil est utilisé dans une applet (« Impossible de continuer le délai. (-1708) »). Jai contourné ce problème en disant directement à AppleScript de gérer la commande de délai au lieu dutiliser « continuer » pour y arriver.]
Le problème est que delay
traite lutilisateur entrée pendant la pause du script, vous pouvez donc toujours cliquer sur les menus ou les fenêtres affichés par une applet, et il y a un bogue (corrigé dans 10.11) où lentrée utilisateur fait que delay
ne pas attendre le durée complète avant de reprendre lexécution du script. Si vous ninteragissez pas avec lapplet, delay
fonctionne correctement.
Commentaires
- Cest tout de ceci un bogue, ou y a-t-il une raison pour laquelle le délai fonctionne de cette façon avec Yosemite?
- Cest un bogue qui retarde ‘ t retarder.
- Cela ‘ est si étrange. Je bricolais avec un applescript qui utilise delay lautre nuit, et soudainement, delay fonctionnait à nouveau correctement. Jai supposé que le bogue avait été corrigé . Une heure plus tard, même si rien navait changé, le bogue était de retour. Je ‘ suis vraiment déconcerté. Cela na ‘ pas dimportance . Je ‘ m en utilisant une variable pour régler lheure et le délai jusquà cinq minutes plus tard (par exemple), et cela ‘ fonctionne parfaitement . Donc … problème résolu, mais cela nexplique pas ‘ pourquoi le problème existe. Intéressant, intéressant, intéressant.
- Parce quApple a fait une gaffe. Apple le logiciel est beaucoup moins fiable depuis quils ont commencé à publier OS X chaque année. Je manque les versions mineures supérieures dOS X (comme 10.6.8) où le système dexploitation était solide comme le roc. Vous navez plus ‘ que ce genre dexpérience.
- Si ‘ est un bug (ce que je suis daccord avec), pourquoi nest-ce pas ‘ que ce nest toujours pas réglé, je me demande. Quelquun ici a-t-il fait un rapport radar? Souhaitez-vous alors poster son identifiant? (ou / aussi poster sur openradar.me)
Réponse
En combattant ce même problème, je suis tombé sur cette réponse à une question pas si liée et a décidé de lessayer et il semble fonctionne pour moi.
Remplacez delay 5
par do shell script "/bin/sleep 5"
et obtenez le même résultat.
Commentaires
- Merci pour le partage! Comme je lai dit plus haut, je ‘ m incapable de tester ceci car, pour des raisons qui nont aucun sens pour moi, le délai 5 fonctionne comme il se doit pour moi en ce moment (je viens de tester il y a un instant). Je nai aucune idée pourquoi cela fonctionne parfois et échoue parfois.Cest si étrange ‘. Jai fini par utiliser une solution de contournement où jobtiens lheure actuelle et la définit comme une variable, puis suspend le script jusquà ce que lheure soit variable plus une minute (pour un délai dune minute, évidemment). Cela ‘ est maladroit, mais ‘ a fonctionné parfaitement pendant des mois, alors qu’un simple retard a été intermittent. Euh.
- Jexécute 10.10.5 et cette solution ne fonctionne pas et verrouille également le script pour la durée du sommeil
- @Greg: Si elle «verrouille le script» pour la durée du sommeil, puis ‘ fonctionne.
/bin/sleep
attend la durée du sommeil et ne revient pas tant quil nest pas terminé. En revanche, la commande ‘ intégrée à AppleScriptdelay
gère les événements dentrée utilisateur pendant que le script est en pause. (Cest là que réside le bogue: sil y a une saisie au clavier de lutilisateur,delay
continue lexécution du script avant la fin du délai.)
Réponse
Je ne dis pas que cest la meilleure solution, mais elle semble avoir résolu mon problème. Au lieu dutiliser un simple délai, qui est ignoré pour des raisons que je ne comprends pas, je suis passé à l’obtention de l’heure et au bouclage jusqu’à ce qu’une nouvelle heure soit atteinte (il utilise toujours un délai, mais peu importe qu’il ignore le délai, car le script ne continue pas jusqu’à ce que heure est atteinte).
# 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
Je meurs toujours denvie de savoir pourquoi le retard est ignoré (ou considérablement accéléré?! ??), mais cela devient le travail fait, aussi maladroit soit-il.
Commentaires
- Le » délai » la commande nest ‘ t étant » accélérée » , il ‘ est interrompu. Pendant le retard, il sassoit dans une boucle vérifiant sil y a des événements dentrée au clavier afin quil puisse vérifier la période de commande. Apparemment, il sort incorrectement de la boucle de retard lorsquune entrée utilisateur est détectée.
- Intéressant! Je ‘ constate que ‘ est ignoré (accéléré? Interrompu?) Même lorsque mon Mac est inactif, mais je ne le fais pas ‘ je ne sais pas pourquoi.
- Une fois quun événement dentrée utilisateur est dans la file dattente dévénements,
delay
continuera à être interrompu jusquà ce que quelque chose gère les événements et les supprime de la file dattente.
Réponse
Jai trouvé un travail- dans un message de forum allemand. Ajoutez ces lignes en haut de votre script:
use framework "Foundation" use scripting additions current application"s NSThread"s sleepForTimeInterval:1
Commentaires
- I ‘ Jai du mal à tester votre réponse car, pour une raison quelconque, le retard fonctionne actuellement comme prévu sur mon Mac. Je ne sais pas pourquoi. Je ‘ m en cours dexécution 10.10.3. Peut-être quApple a corrigé ce bogue? Ou peut-être que ‘ est juste un problème intermittent qui n ‘ naffecte pas mon Mac en ce moment. Pouah. Comme je lai dit ci-dessus cependant, ma solution de contournement consiste à demander à Applescript dobtenir lheure actuelle, puis de retarder lheure actuelle plus x.
- Jutilise également 10.10.3 et je vois toujours le problème. Puisque tout le monde ne voit pas le problème, il ‘ est probablement intermittent ou lié à un logiciel tiers ou à certains paramètres de préférence. Qui sait. BTW, votre solution de rechange présente probablement linconvénient que lapplication continue à utiliser 100% du temps CPU en attendant, alors que le comportement de retard approprié consiste à mettre lapplication en veille pendant cette durée, ce qui consomme moins dénergie.
- Jutilise 10.10.5 et cette solution ne fonctionne pas.
- @ThomasTempelmann: Le problème se produit lorsquil y a une entrée utilisateur. Si vous ne ‘ t cliquez ou tapez pendant que le script est en cours d’exécution, le bogue n’est ‘ pas déclenché.
- Notez que cette solution provoque le gel de lapplication pendant la durée du sommeil.
delay
traite les entrées utilisateur pendant que le script est en pause, afin que vous puissiez toujours interagir avec les menus et les fenêtres, par exemple.
Réponse
carzyj avait ce que je considère comme la meilleure réponse, mais combiné à la méthode de Chris Page, vous obtenez:
on delay duration do shell script "/bin/sleep " & duration end delay
Vous pouvez commenter « on delay » à « end delay » pour revenir au délai dorigine.
Commentaires
- I a également fait une modification de code similaire, avant de voir cela. Jexécute 10.10.5 et cette solution ne fonctionne pas et verrouille également le script pour la durée du sommeil.
Réponse
ceci est une modification de la solution @ chris-page
Cela semble être un équilibre entre la réactivité et la capture précise du retard.
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
Mais au lieu de dire à Applescript de retarder pour la durée globale, nous lui disons simplement de retarder pendant une période fractionnaire de la durée. si la période est inférieure à ce que Apple permet (1/60 de seconde), alors réglons-le simplement sur ce delta. Que nous pouvons garder une certaine réactivité, tout en restant précis. le soupçon est que parfois le retard ne « t fonctionne pour que la boucle de répétition while maintienne le thread verrouillé, mais dans les scénarios de réussite, nous voulons que le delta de retard soit court afin que le processus puisse toujours être interrompu
Commentaires
- Raccourcir le délai demandé est inutile et ne peut que ralentir lexécution du script et consommer plus de CPU en attendant. Ma version appelle simplement le délai jusquà ce que toute la durée souhaitée se soit écoulée, ce qui permet à
delay
de retarder autant que possible avant de continuer lexécution. - Notez que depuis cette réponse a été publiée, jai mis à jour mon code pour utiliser
delay endTime - (current date)
au lieu dedelay duration
, ce qui garantit que sidelay
ne ‘ t être interrompu il na pas ‘ mettre le script en pause plus longtemps que lheure initialement demandée , qui est peut-être ce à quoi vous tentiez de répondre avec cette réponse.
Réponse
Donc, pour mettre tout cela ensemble, je crois que Chris veut dire ceci:
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