Merk: Problemet med delay
ble løst i OS X 10.11 El Capitan.
Helt siden jeg oppgraderte til Yosemite, har Applescripts som bruker forsinkelser sluttet å fungere . Hvordan kan jeg fikse dette?
Her er verdens enkleste Applescript, for et enkelt eksempel:
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
Det bør ta 30 sekunder å fullføre. Hvis jeg kjører den i Script Editor (tidligere Applescript Editor), tar det 30 sekunder å fullføre. Men hvis jeg lagrer dette skriptet som en app, ignoreres forsinkelsene når jeg starter appen, og appen tar et brøkdel av et sekund å fullføre.
Hvordan kan jeg tvinge Applescript til å forsinke for et spesifisert beløp tid før du går videre til neste trinn? Er dette en Yosemite-feil? Er det en pålitelig løsning?
Kommentarer
- Dette fungerer som forventet på min Mac (10.10.1)
- Noen ideer hva får det til å ikke fungere på min? For å avklare: det fungerer i Script Editor, men hvis jeg lagrer skriptet som en app og deretter starter appen, blir forsinkelsene ignorert. Det ‘ er det merkeligste.
- Jeg har det samme problemet den 10.10.3
- Rapportert til Apple: openradar.me/21588747
- Dette problemet ble løst i OS X 10.11 El Capitan.
Svar
Merk: Problemet med delay
ble løst i OS X 10.11 El Capitan.
@ 2oh1, du har den rette grunnideen i svaret ditt, men her» er et fullstendig og riktig svar:
Den eneste rimelige måten å omgå dette på er å påkalle «forsinkelse» i en sløyfe som sikrer at ønsket varighet går før du fortsetter. Den beste måten å gjøre dette på er å overstyre «forsinkelse» med en tilpasset behandler:
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
Dette lar deg la resten av skriptet være uendret, og du kan bruke «forsinkelse» normalt, f.eks.
delay 5 display alert "I like cake!"
[MERK: Normalt vil den tilpassede behandleren bruke «fortsett forsinkelsesvarighet» for å påkalle den innebygde «forsinkelsen», men jeg fant ut at selv om dette fungerer i Script Editor, returnerer den en feil når den brukes i en applet («Cant continue delay.» (-1708) ”). Jeg jobbet rundt det problemet ved å direkte be AppleScript om å håndtere forsinkelseskommandoen i stedet for å bruke «fortsett» for å komme dit.]
Problemet er at delay
behandler brukeren inngang mens du pauser skriptet, slik at du fremdeles kan klikke på menyer eller vinduer som vises av en applet, og det er en feil (løst i 10.11) der brukerinngang fører til at delay
ikke venter på full varighet før du fortsetter skriptutførelsen. Hvis du ikke kommuniserer med appleten, fungerer delay
riktig.
Kommentarer
- Er alt av dette en feil, eller er det en grunn til at forsinkelse fungerer på denne måten med Yosemite?
- Det er en feil som forsinkelse ikke ‘ t forsinker.
- Det ‘ er så rart. Jeg flikket med et epleskrift som bruker forsinkelse den andre natten, og plutselig fungerte forsinkelsen riktig igjen. Jeg antok at feilen var løst En time senere, selv om ingenting hadde endret seg, var feilen tilbake. Jeg ‘ er virkelig forvirret. Det betyr ikke ‘ . Jeg ‘ bruker en variabel for å stille tid og forsinkelse til fem minutter senere (for eksempel), og den ‘ fungerer perfekt Så … problemet er løst, men det forklarer ikke ‘ hvorfor problemet eksisterer. Interessant, interessant, interessant.
- Fordi Apple var dumt. Apple programvaren er mye mindre pålitelig siden de begynte å gi ut OS X årlig. Jeg savner de høyere OS X-mindre versjonene (som 10.6.8) der operativsystemet var solid. Du får bare ikke ‘ den slags opplevelse lenger.
- Hvis det ‘ er en feil (som jeg er enig med), hvorfor er ikke ‘ t dette fortsatt ikke løst, lurer jeg på. Har noen her laget en radarrapport? Vil du da legge ut ID-en? (eller / legg også ut på openradar.me)
Svar
Mens jeg kjempet mot det samme problemet, kom jeg over dette svaret på et ikke-så-relatert spørsmål og bestemte oss for å prøve det og det ser ut til å jobbe for meg.
Erstatt delay 5
med do shell script "/bin/sleep 5"
og få samme resultat.
Kommentarer
- Takk for delingen! Som jeg sa tidligere ovenfor, er jeg ‘ ikke i stand til å teste dette fordi forsinkelse 5 av grunner som ikke gir mening for meg fungerer som det skal for meg akkurat nå (jeg har nettopp testet det igjen for et øyeblikk siden). Jeg aner ikke hvorfor dette noen ganger fungerer og noen ganger mislykkes.Det ‘ er så rart. Jeg endte opp med å bruke en løsning der jeg får den gjeldende tiden og setter den som en variabel, og setter deretter skriptet på pause til tiden er variabel pluss ett minutt (for en forsinkelse på 1 minutt, tydeligvis). Det ‘ er klumpete, men det ‘ har virket feilfritt i flere måneder, mens en enkel forsinkelse har vært intermitterende. Uhg.
- Jeg kjører 10.10.5, og denne løsningen fungerer ikke, og låser også skriptet mens du sover.
- @Greg: Hvis det «låser skriptet» for søvnvarigheten, så fungerer den ‘.
/bin/sleep
venter på søvnvarigheten og kommer ikke tilbake før den er fullført. Derimot håndterer AppleScript ‘ s innebygdedelay
kommandoer av brukerinngang mens skriptet er midlertidig stoppet. (Som er der feilen ligger: Hvis det er tastaturinngang fra brukeren, fortsetterdelay
kjøring av skriptet før forsinkelsens varighet er fullført.)
Svar
Jeg sier ikke dette er den beste løsningen, men det ser ut til å ha løst problemet mitt. I stedet for å bruke en enkel forsinkelse, som blir ignorert Av grunner som jeg ikke forstår, har jeg gått over til å få tiden og løkke til en ny tid er nådd (den bruker fortsatt en forsinkelse, men det spiller ingen rolle om den ignorerer forsinkelsen siden skriptet ikke fortsetter til tiden er nådd).
# 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
Jeg er fremdeles ute etter å vite hvorfor forsinkelse blir ignorert (eller dramatisk spurt opp?! ??), men dette blir jobben gjort, klønete som den er.
Kommentarer
- » forsinkelse » kommandoen er ikke ‘ t blir » fremskyndet » , det ‘ avbrytes. Mens den forsinkes, sitter den i en løkke og sjekker om det er noen tastaturinntakshendelser, slik at den kan se etter kommandoperiode. Tilsynelatende går den feil ut av forsinkelsessløyfen når noen brukerinndata blir oppdaget.
- Interessant! Jeg ‘ finner ut at den ‘ blir ignorert (sped up? Avbrutt?) Selv når Mac-en min sitter inaktiv, men jeg vet ikke ‘ vet ikke hvorfor.
- Når en brukerinntakshendelse er i hendelseskøen, vil
delay
fortsette å bli avbrutt til noe håndterer hendelsene og fjerner dem fra køen.
Svar
Jeg fant et arbeid- rundt i et tysk foruminnlegg . Legg til disse linjene øverst i skriptet ditt:
use framework "Foundation" use scripting additions current application"s NSThread"s sleepForTimeInterval:1
Kommentarer
- I ‘ Jeg har problemer med å teste svaret ditt, uansett årsak, fungerer forsinkelse for øyeblikket som forventet på min Mac. Jeg aner ikke hvorfor. Jeg ‘ kjører 10.10.3. Kanskje Apple løste denne feilen? Eller kanskje er det ‘ bare et periodisk problem som ikke ‘ ikke påvirker Mac-en min for øyeblikket. Ugh. Som jeg sa ovenfor, er løsningen min imidlertid å få Applescript til å få gjeldende tid og deretter forsinke til nåværende tid pluss x.
- Jeg kjører også 10.10.3 og ser fortsatt problemet. Siden ikke alle ser problemet, er det ‘ sannsynligvis periodisk eller relatert til tredjepartsprogramvare eller til visse innstillingsinnstillinger. Hvem vet. BTW, jobben din har sannsynligvis den ulempen at appen fortsetter å bruke 100% CPU-tid mens du venter, mens riktig forsinkelsesadferd er å sette appen i dvale i den varigheten, og dermed bruke mindre strøm.
- Jeg kjører 10.10.5, og denne løsningen fungerer ikke.
- @TomasTempelmann: Problemet oppstår når det er brukerinngang. Hvis du ikke klikker eller skriver ‘ mens skriptet kjører, er ikke feilen ‘ t utløst.
- Merk at denne løsningen fører til at applikasjonen faktisk fryser så lenge du sover.
delay
behandler brukerinngang mens skriptet er midlertidig stoppet, slik at du for eksempel fortsatt kan samhandle med menyer og vinduer.
Svar
carzyj hadde det jeg anser som det beste svaret, men når det kombineres med Chris Pays metode, får du:
on delay duration do shell script "/bin/sleep " & duration end delay
Du kan kommentere «på forsinkelse» til «sluttforsinkelse» for å gå tilbake til den opprinnelige forsinkelsen.
Kommentarer
- I gjorde også en lignende kodemodifisering før jeg så dette. Jeg kjører 10.10.5 og denne løsningen fungerer ikke og låser også skriptet mens du sover.
Svar
dette er en modifisering av @ chris-side-løsning
Det ser ut til å være en balanse mellom respons og nøyaktig fangst av forsinkelsen.
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
Men i stedet for å be Applescript om å forsinke for den totale varigheten, ber vi bare om at den skal forsinke i en brøkperiode av varigheten. hvis perioden er mindre enn hva eple tillater (1/60 av et sekund), så la oss bare sette det til det deltaet. At vi kan beholde litt respons, men likevel være nøyaktige. mistanken er at noen ganger forsinkelse ikke fungere slik at repetisjon mens sløyfe holder tråden låst, men i suksessscenarier vil vi at forsinkelsesdeltaet skal være kort, slik at prosessen fortsatt kan avbrytes
Kommentarer
- Å forkorte den valgte forsinkelsen er unødvendig og kan bare gjøre at skriptet kjører tregere og bruker mer CPU mens du venter. Min versjon kaller bare forsinkelse til hele ønsket varighet har gått, slik at
delay
kan forsinke så mye det kan før den fortsetter kjøringen. - Merk at siden dette svaret ble lagt ut, oppdaterte jeg koden min for å bruke
delay endTime - (current date)
i stedet fordelay duration
, noe som sikrer at hvisdelay
blir ikke ‘ t avbrutt, det vant ‘ t pause skriptet lenger enn opprinnelig ønsket tid , som kan ha vært det du prøvde å ta opp med dette svaret.
Svar
Så for å si alt sammen tror jeg Chris mener dette:
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