Notă: Problema cu delay
a fost remediată în OS X 10.11 El Capitan.
De când am trecut la Yosemite, Applescripturile care folosesc întârzieri au încetat să mai funcționeze . Cum pot remedia această problemă?
Aici este cel mai simplu Applescript din lume, pentru un exemplu ușor:
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
Acest lucru ar trebui să dureze 30 de secunde până la finalizare. Dacă îl rulez în Script Editor (anterior Applescript Editor) durează 30 de secunde până la finalizare. Dar dacă salvez acest script ca aplicație, când lansez aplicația, întârzierile sunt ignorate și aplicația durează o fracțiune de secundă.
Cum pot forța Applescript să întârzie pentru o cantitate specificată de timp înainte de a trece la pasul următor? Este o problemă Yosemite? Există o soluție fiabilă?
Comentarii
- Acest lucru funcționează conform așteptărilor pe Mac-ul meu (10.10.1)
- Orice idee ce o face să nu funcționeze pe a mea? Pentru a clarifica: funcționează în Editorul de scripturi, dar dacă salvez scriptul ca aplicație și apoi lansez aplicația, întârzierile sunt ignorate. ‘ este cel mai ciudat lucru.
- Am aceeași problemă la 10.10.3
- Raportat la Apple: openradar.me/21588747
- Această problemă a fost rezolvată în OS X 10.11 El Capitan.
Răspuns
Notă: Problema cu a fost remediat în OS X 10.11 El Capitan.
@ 2oh1, aveți ideea de bază corectă în răspunsul dvs., dar aici este un răspuns complet și corect:
Singurul mod rezonabil de a rezolva acest lucru este invocarea „întârzierii” într-o buclă care asigură durata dorită care trece înainte de a continua. Cel mai bun mod de a face acest lucru este de a suprascrie „întârzierea” cu un handler personalizat:
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
Acest lucru vă permite să lăsați restul scriptului neschimbat și puteți utiliza „întârziere” în mod normal, de exemplu,
delay 5 display alert "I like cake!"
[NOTĂ: În mod normal, gestionarul personalizat va utiliza „durata întârzierii continue” pentru a invoca „întârziere” încorporată, dar am constatat că, deși acest lucru funcționează în Editorul de scripturi, returnează o eroare atunci când este utilizat într-un applet („Nu se poate continua întârzierea. (-1708) ”). Am rezolvat această problemă spunându-i direct AppleScript să gestioneze comanda de întârziere în loc să folosesc „continue” pentru a ajunge acolo.]
Problema este că delay
procesează utilizatorul de intrare în timp ce pauzați scriptul, astfel încât să puteți face clic pe meniurile sau ferestrele afișate de un applet și există o eroare (rezolvată în 10.11) în care introducerea utilizatorului face ca delay
să nu aștepte durata completă înainte de a relua executarea scriptului. Dacă nu interacționați cu applet-ul, delay
funcționează corect.
Comentarii
- Este totul din aceasta este o eroare sau există un motiv pentru care întârzierea funcționează în acest fel cu Yosemite?
- Este o eroare care întârzia nu este întârziată.
- Este ‘ atât de ciudat. Am jucat cu un applescript care folosește întârziere noaptea trecută și, brusc, întârzierea a funcționat din nou corect. Am presupus că eroarea a fost remediată. . O oră mai târziu, chiar dacă nu s-a schimbat nimic, eroarea s-a întors. Am ‘ cu adevărat nedumerit. Nu contează ‘ . ‘ M folosind o variabilă pentru a seta timpul și întârziere până la cinci minute mai târziu (de exemplu) și ‘ funcționează perfect . Deci … problema a fost rezolvată, dar asta nu ‘ nu explică de ce există problema. Interesant, interesant, interesant.
- Deoarece Apple a păcălit. Apple software-ul este mult mai puțin fiabil de când au început să lanseze OS X anual. Mi-e dor de versiunile minore OS X superioare (cum ar fi 10.6.8) în care sistemul de operare era solid. Doar nu mai ‘ nu mai primești acest gen de experiență.
- Dacă ‘ este o eroare (ceea ce sunt de acord) cu), de ce nu este ‘ acest lucru încă nu este remediat, mă întreb. A făcut cineva aici un raport radar? Ați dori, apoi, să postați actul de identitate? (sau / și postarea pe openradar.me)
Răspuns
În timp ce mă luptam cu aceeași problemă, am dat peste acest răspuns la o întrebare care nu este atât de legată și a decis să îl încerce și se pare că lucrează pentru mine.
Înlocuiți delay 5
cu do shell script "/bin/sleep 5"
și obțineți același rezultat.
Comentarii
- Vă mulțumim pentru distribuire! Așa cum am spus mai sus, ‘ nu pot testa acest lucru deoarece, din motive care nu au sens pentru mine, întârzierea 5 funcționează așa cum ar trebui pentru mine chiar acum (tocmai am testat din nou acum o clipă). Habar n-am de ce funcționează uneori și uneori eșuează.Este ‘ atât de ciudat. Am ajuns să folosesc o soluție în care obțin ora curentă și o setez ca variabilă, apoi întrerup scriptul până când timpul este variabil plus un minut (pentru o întârziere de 1 minut, evident). ‘ este greoi, dar ‘ a funcționat fără cusur luni de zile, în timp ce o simplă întârziere a fost intermitentă. Uh.
- Execut 10.10.5 și această soluție nu funcționează și, de asemenea, blochează scriptul pe durata somnului
- @Greg: Dacă „blochează scriptul” pentru durata somnului, apoi ‘ funcționează.
/bin/sleep
așteaptă durata somnului și nu se întoarce decât după ce a terminat. În schimb, comanda încorporată ‘ AppleScriptdelay
gestionează evenimentele de intrare ale utilizatorului în timp ce scriptul este întrerupt. (Care este locul în care se află bug-ul: dacă există introducerea tastaturii utilizatorului,delay
continuă executarea scriptului înainte de finalizarea duratei de întârziere.)
Răspuns
Nu spun că aceasta este cea mai bună soluție, dar se pare că a rezolvat problema mea. În loc să folosesc o întârziere simplă, care este ignorată din motive pe care nu le înțeleg, am trecut la obținerea timpului și a looping-ului până când se atinge un nou timp (utilizează încă o întârziere, dar nu contează dacă ignoră întârzierea, deoarece scriptul nu continuă până când timpul este atins).
# 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
Încă mor pentru a ști de ce întârzierea este ignorată (sau accelerată dramatic?! ??), dar acest lucru devine treaba făcută, neîndemânatică.
Comentarii
- ” întârziere ” nu este ‘ t ” accelerată ” , este ‘ este întrerupt. În timp ce întârzie, stă într-o buclă verificând dacă există evenimente de intrare de la tastatură, astfel încât să poată verifica perioada de comandă. Se pare că iese incorect din bucla de întârziere atunci când este detectată orice intrare de utilizator.
- Interesant! ‘ constat că ‘ este ignorat (accelerat? Întrerupt?) Chiar și atunci când Mac-ul meu stă inactiv, dar nu ‘ nu știu de ce.
- Odată ce un eveniment de introducere a utilizatorului se află în coada de evenimente,
delay
va continua să să fie întrerupt până când ceva tratează evenimentele și le elimină din coadă.
Răspuns
Am găsit o lucrare- în jur într-o postare germană din forum . Adăugați aceste rânduri în partea de sus a scriptului:
use framework "Foundation" use scripting additions current application"s NSThread"s sleepForTimeInterval:1
Comentarii
- I Am probleme la testarea răspunsului dvs., deoarece, din orice motiv, întârzierea funcționează în prezent, așa cum era de așteptat, pe Mac-ul meu. Habar n-am de ce. Eu ‘ rulez 10.10.3. Poate că Apple a remediat această problemă? Sau, poate ‘ este doar o problemă intermitentă care nu ‘ îmi afectează Mac-ul în acest moment. Ugh. Așa cum am spus mai sus, soluția mea este ca Applescript să obțină ora curentă și apoi să întârzie până la ora curentă plus x.
- Execut și 10.10.3 și văd în continuare problema. Întrucât nu toată lumea vede problema, aceasta ‘ este probabil intermitentă sau legată de software-ul terților sau de anumite setări de preferință. Cine știe. BTW, rezolvarea dvs. are probabil dezavantajul că aplicația continuă să utilizeze 100% timp CPU în timp ce așteaptă, în timp ce comportamentul corect de întârziere este de a pune aplicația în repaus pentru acea durată, folosind astfel mai puțină energie. Execut 10.10.5 și această soluție nu funcționează.
- @ThomasTempelmann: Problema apare atunci când există intrări de utilizator. Dacă nu ‘ nu faceți clic sau tastați în timp ce scriptul rulează, eroarea nu este declanșată ‘ t declanșată.
- Rețineți că această soluție face ca aplicația să înghețe efectiv pe durata somnului.
delay
procesează introducerea utilizatorului în timp ce scriptul este întrerupt, astfel încât să puteți interacționa cu meniurile și ferestrele, de exemplu.
Răspuns
carzyj a avut ceea ce consider cel mai bun răspuns, dar atunci când este combinat cu metoda lui Chris Page, veți obține:
on delay duration do shell script "/bin/sleep " & duration end delay
Puteți comenta „întârziere” până la „întârziere finală” pentru a reveni la întârzierea inițială.
Comentarii
- I De asemenea, am făcut o modificare de cod similară, înainte de a vedea acest lucru. Execut 10.10.5 și această soluție nu funcționează și, de asemenea, blochează scriptul pentru durata somnului.
Răspuns
aceasta este o modificare a soluției @ chris-page
Se pare că este un echilibru între capacitatea de reacție și captarea exactă a întârzierii.
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
Dar, în loc să spunem Applescript să întârzie pentru durata totală, îi spunem doar să întârzie pentru o perioadă fracționată a duratei. dacă perioada este mai mică decât ceea ce permite mărul (1/60 dintr-o secundă), atunci să o setăm la delta respectivă. Că putem păstra o anumită reacție, dar totuși să fim corecți. Banuiala este că uneori întârzierea nu este funcționează astfel încât repetarea în buclă să mențină firul blocat, dar în scenariile de succes, dorim ca delta de întârziere să fie scurtă, astfel încât procesul să poată fi întrerupt
Comentarii
- Scurtarea întârzierii solicitate nu este necesară și poate face ca scriptul să ruleze mai lent și să consume mai mult CPU în timp ce așteptați. Versiunea mea face doar apeluri de întârziere până la expirarea întregii durate dorite, permițând
delay
să întârzie cât mai mult înainte de a continua execuția. - Rețineți că, din acest răspuns a fost postat, mi-am actualizat codul pentru a utiliza
delay endTime - (current date)
în loc dedelay duration
, ceea ce asigură că dacădelay
nu ‘ t se întrerupe, a câștigat ‘ t întrerupeți scriptul mai mult decât timpul solicitat inițial , care ar fi putut fi ceea ce încercați să abordați cu acest răspuns.
Răspuns
Deci, pentru a pune totul împreună, cred că Chris înseamnă asta:
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