AppleScript-kommandoen “forsinkelse” fungerer ikke siden skift til Yosemite

Bemærk: Problemet med delay blev løst i OS X 10.11 El Capitan.

Lige siden jeg opgraderede til Yosemite, har Applescripts, der bruger forsinkelser, stoppet med at fungere . Hvordan kan jeg løse dette?

Her er verdens enkleste appelskript af hensyn til et let 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 skal tage 30 sekunder at gennemføre. Hvis jeg kører det i Script Editor (tidligere Applescript Editor), tager det 30 sekunder at fuldføre. Men hvis jeg gemmer dette script som en app, ignoreres forsinkelserne, når appen startes, og appen tager et brøkdel af et sekund at gennemføre.

Hvordan kan jeg tvinge Applescript til at udsætte et bestemt beløb tid inden vi går videre til næste trin? Er dette en Yosemite-fejl? Er der en pålidelig løsning?

Kommentarer

  • Dette fungerer som forventet på min Mac (10.10.1)
  • Enhver idé hvad får det til ikke at arbejde på min? For at præcisere: det fungerer i Script Editor, men hvis jeg gemmer scriptet som en app og derefter starter appen, ignoreres forsinkelserne. Det ‘ er den mærkeligste ting.
  • Jeg har det samme problem den 10.10.3
  • Rapporteret til Apple: openradar.me/21588747
  • Dette problem blev løst i OS X 10.11 El Capitan.

Svar

Bemærk: Problemet med delay blev rettet i OS X 10.11 El Capitan.

@ 2oh1, du har den rigtige grundidee i dit svar, men her” er et komplet og korrekt svar:

Den eneste rimelige måde at omgå dette på er at påberåbe sig “forsinkelse” i en løkke, der sikrer, at den ønskede varighed er gået, inden du fortsætter. Den bedste måde at gøre dette på er at tilsidesætte “forsinkelse” med en brugerdefineret handler:

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 giver dig mulighed for at lade resten af dit script være uændret, og du kan bruge “forsinkelse” normalt, f.eks.

delay 5 display alert "I like cake!" 

[BEMÆRK: Normalt bruger den brugerdefinerede handler “fortsæt forsinkelsesvarighed” til at påkalde den indbyggede “forsinkelse”, men jeg fandt ud af, at selvom dette fungerer i Script Editor, returnerer det en fejl, når den bruges i en applet (“Kan ikke fortsætte forsinkelsen. (-1708) ”). Jeg løste problemet ved direkte at bede AppleScript om at håndtere forsinkelseskommandoen i stedet for at bruge “fortsæt” for at komme derhen.]

Problemet er, at delay behandler brugeren input, mens du sætter scriptet på pause, så du stadig kan klikke på menuer eller vinduer, der vises af en applet, og der er en fejl (rettet i 10.11), hvor brugerinput får delay til ikke at vente på fuld varighed inden genoptagelse af script genoptages. Hvis du ikke interagerer med appleten, fungerer delay korrekt.

Kommentarer

  • Er alt heraf en fejl, eller er der en grund til, at forsinkelse fungerer på denne måde med Yosemite?
  • Det er en fejl, der forsinker ikke ‘ t forsinker.
  • Det ‘ er så mærkeligt. Jeg flimrede med et æbleskrift, der bruger forsinkelse den anden nat, og pludselig fungerede forsinkelse igen korrekt. Jeg antog, at fejlen var rettet En time senere, selvom intet havde ændret sig, var fejlen tilbage. Jeg ‘ er virkelig forbløffet. Det betyder ikke ‘ dog . Jeg ‘ bruger en variabel til at indstille tid og forsinkelse indtil 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 dårligt. Apple software er meget mindre pålidelig, siden de begyndte at frigive OS X årligt. Jeg savner de højere OS X-mindre versioner (som 10.6.8), hvor operativsystemet var solidt. Du får bare ikke ‘ den slags oplevelse længere.
  • Hvis det ‘ er en fejl (som jeg er enig med), hvorfor er ‘ t dette stadig ikke løst, undrer jeg mig. Har nogen her lavet en radarrapport? Vil du så venligst sende dets ID? (eller / post også på openradar.me)

Svar

Mens jeg kæmpede med det samme problem stødte jeg på dette svar på et ikke-så-relateret spørgsmål og besluttede at prøve det, og det ser ud til at arbejde for mig.

Erstat delay 5 med do shell script "/bin/sleep 5" og få det samme resultat.

Kommentarer

  • Tak for deling! Som jeg sagde tidligere ovenfor, er jeg ‘ ikke i stand til at teste dette, fordi forsinkelse 5 af grunde, der ikke giver mening for mig, fungerer som det skal for mig lige nu (jeg har lige testet det igen for et øjeblik siden). Jeg har ingen idé om, hvorfor dette nogle gange fungerer og nogle gange fejler.Det ‘ er så mærkeligt. Jeg endte med at bruge en løsning, hvor jeg får den aktuelle tid og indstiller den som en variabel, og sætter derefter scriptet på pause, indtil tiden er variabel plus et minut (med en forsinkelse på 1 minut, selvfølgelig). Det ‘ er klodset, men det ‘ har arbejdet fejlfrit i flere måneder, mens en simpel forsinkelse har været intermitterende. Uhg.
  • Jeg kører 10.10.5, og denne løsning fungerer ikke og låser også scriptet i søvnvarighed
  • @Greg: Hvis det “låser scriptet” i søvnvarigheden, så fungerer den ‘. /bin/sleep venter på søvnvarigheden og vender ikke tilbage, før den er afsluttet. I modsætning hertil håndterer AppleScript ‘ s indbyggede delay kommando for brugerinput, mens scriptet er sat på pause. (Hvilket er der, hvor fejlen ligger: hvis der er input fra brugerens tastatur, fortsætter delay scriptudførelse, før forsinkelsens varighed er afsluttet.)

Svar

Jeg siger ikke, det er den bedste løsning, men det ser ud til at have løst mit problem. I stedet for at bruge en simpel forsinkelse, som ignoreres Af grunde, som jeg ikke forstår, har jeg skiftet til at få tiden og løkke, indtil et nyt tidspunkt er nået (det bruger stadig en forsinkelse, men det betyder ikke noget, hvis det ignorerer forsinkelsen, da scriptet ikke fortsætter, indtil tiden er nået).

# 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 stadig ved at vide, hvorfor forsinkelse ignoreres (eller dramatisk fremskyndes?! ??), men dette bliver jobbet udført, klodset som det er.

Kommentarer

  • ” forsinkelse ” kommandoen er ‘ t bliver ” fremskyndet ” , det ‘ afbrydes. Mens det forsinkes, sidder det i en løkke, der kontrollerer, om der er nogen tastaturinputhændelser, så det kan kontrollere, om der er kommandoperiode. Det går tilsyneladende forkert ud af forsinkelsessløjfen, når der registreres brugerinput.
  • Interessant! Jeg ‘ finder ud af, at det ‘ ignoreres (hurtigere? Afbrudt?), Selv når min Mac sidder inaktiv, men jeg gør det ikke ‘ ved ikke hvorfor.
  • Når en brugerinputhændelse er i begivenhedskøen, fortsætter delay til afbrydes, indtil noget håndterer begivenhederne og fjerner dem fra køen.

Svar

Jeg fandt et arbejde- rundt i et tysk forumindlæg . Tilføj disse linjer øverst på dit script:

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

Kommentarer

  • I ‘ Jeg har problemer med at teste dit svar, fordi forsinkelse uanset årsag i øjeblikket fungerer som forventet på min Mac. Jeg aner ikke hvorfor. Jeg ‘ m kører 10.10.3. Måske fik Apple denne fejl? Eller måske er det ‘ bare et intermitterende problem, der ikke ‘ ikke påvirker min Mac i øjeblikket. Ugh. Som jeg sagde ovenfor, er min løsning imidlertid, at Applescript får den aktuelle tid og derefter forsinker indtil den aktuelle tid plus x.
  • Jeg kører også 10.10.3 og ser stadig problemet. Da ikke alle ser problemet, er det ‘ sandsynligvis intermitterende eller relateret til tredjepartssoftware eller til bestemte præferenceindstillinger. Hvem ved. BTW, dit arbejde har sandsynligvis den ulempe, at appen fortsætter med at bruge 100% CPU-tid, mens du venter, mens den korrekte forsinkelsesadfærd er at sætte appen i dvale i den varighed og derved bruge mindre strøm.
  • Jeg kører 10.10.5, og denne løsning fungerer ikke.
  • @TomasTempelmann: Problemet opstår, når der er brugerinput. Hvis du ikke ‘ ikke klikker eller skriver, mens scriptet kører, er fejlen ikke ‘ t udløst.
  • Bemærk, at denne løsning får applikationen til at fryse i søvnens varighed. delay behandler brugerinput, mens scriptet er sat på pause, så du f.eks. stadig kan interagere med menuer og vinduer.

Svar

carzyj havde det, jeg anser for det bedste svar, men når det kombineres med Chris Pages metode, får du:

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

Du kan kommentere “på forsinkelse” til “slutforsinkelse” for at vende tilbage til den oprindelige forsinkelse.

Kommentarer

  • I foretog også en lignende kodemodifikation, før jeg så dette. Jeg kører 10.10.5, og denne løsning fungerer ikke og låser også scriptet i søvnvarighed.

Svar

dette er en ændring af @ chris-sideløsning

Det ser ud til at være en balance mellem lydhørhed og præcis indfangning af 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 at bede Applescript om at udsætte den samlede varighed, fortæller vi det bare at udsætte i en brøkperiode af varigheden. hvis perioden er mindre end hvad apple tillader (1/60 af et sekund), så lad os bare indstille det til det delta. At vi kan bevare noget lydhørhed, men alligevel være nøjagtige. Mistanken er, at forsinkelse undertiden ikke arbejde, så gentagelse mens sløjfe holder tråden låst, men i succes scenarier ønsker vi, at forsinkelsesdeltaet er kort, så processen stadig kan afbrydes

Kommentarer

  • Forkortelse af den anmodede forsinkelse er unødvendig og kan kun få scriptet til at køre langsommere og forbruge mere CPU, mens du venter. Min version kalder kun forsinkelse, indtil hele den ønskede varighed er forløbet, så delay kan udsætte så meget som muligt, før den fortsætter udførelsen.
  • Bemærk, at da dette svar blev sendt, opdaterede jeg min kode til at bruge delay endTime - (current date) i stedet for delay duration, hvilket sikrer, at hvis delay afbrydes ikke ‘ t det vinder ‘ t pause scriptet længere end den oprindeligt anmodede tid , hvilket muligvis har været det, du prøvede at adressere med dette svar.

Svar

Så for at sætte 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 

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *