Opmerking: Het probleem met delay
is opgelost in OS X 10.11 El Capitan.
Sinds ik een upgrade naar Yosemite heb uitgevoerd, werken Applescripts die vertragingen gebruiken niet meer . Hoe kan ik dit oplossen?
Hier is s werelds eenvoudigste Applescript, voor een eenvoudig voorbeeld:
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
Dat duurt 30 seconden om te voltooien. Als ik het in Script Editor (voorheen Applescript Editor) uitvoer, duurt het 30 seconden om te voltooien. Maar als ik dit script als een app opsla, worden de vertragingen bij het starten van de app genegeerd en duurt het een fractie van een seconde voordat de app is voltooid.
Hoe kan ik Applescript dwingen om een bepaald bedrag uit te stellen tijd voordat u doorgaat naar de volgende stap? Is dit een fout in Yosemite? Is er een betrouwbare oplossing?
Opmerkingen
- Dit werkt zoals verwacht op mijn Mac (10.10.1)
- Enig idee wat zorgt ervoor dat het niet werkt op de mijne? Ter verduidelijking: het werkt in Script Editor, maar als ik het script als app opsla en vervolgens de app start, worden de vertragingen genegeerd. Het ‘ is het vreemdste.
- Ik heb hetzelfde probleem op 10.10.3
- Gerapporteerd aan Apple: openradar.me/21588747
- Dit probleem is opgelost in OS X 10.11 El Capitan.
Antwoord
Opmerking: Het probleem met delay
is opgelost in OS X 10.11 El Capitan.
@ 2oh1, je hebt het juiste basisidee in je antwoord, maar hier” is een compleet en juist antwoord:
De enige redelijke manier om dit te omzeilen, is door “vertraging” aan te roepen binnen een lus die ervoor zorgt dat de gewenste duur verstrijkt voordat verder wordt gegaan. De beste manier om dit te doen is om “vertraging” te negeren met een aangepaste 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
Hiermee kunt u de rest van uw script ongewijzigd laten en kunt u “delay” normaal gebruiken, bijvoorbeeld
delay 5 display alert "I like cake!"
[OPMERKING: Normaal gesproken zou de aangepaste handler “continue vertragingstijd” gebruiken om aan te roepen de ingebouwde “vertraging”, maar ik ontdekte dat, hoewel dit werkt binnen Script Editor, het een fout retourneert bij gebruik in een applet (“Kan niet doorgaan met vertraging. (-1708) ”). Ik heb dat probleem omzeild door AppleScript rechtstreeks te vertellen om de vertragingsopdracht af te handelen in plaats van “continue” te gebruiken om daar te komen.]
Het probleem is dat delay
de gebruiker verwerkt invoer tijdens het pauzeren van het script, dus u kunt nog steeds op menus of vensters klikken die door een applet worden weergegeven, en er is een bug (opgelost in 10.11) waarbij gebruikersinvoer ervoor zorgt dat delay
niet wacht op de volledige duur voordat de uitvoering van het script wordt hervat. Als je geen interactie hebt met de applet, delay
werkt correct.
Reacties
- Is alles hiervan een bug, of is er een reden waarom vertraging op deze manier werkt met Yosemite?
- Het is een bug die vertraging niet ‘ t vertraagt.
- Het ‘ is zo vreemd. Ik was gisteravond aan het sleutelen aan een appelscript dat vertraging gebruikt, en plotseling werkte vertraging weer correct. Ik nam aan dat de bug was verholpen . Een uur later, hoewel er niets was veranderd, was de bug terug. Ik ‘ ben echt verbijsterd. Het doet ‘ er echter niet toe . Ik ‘ m gebruik een variabele om de tijd en vertraging tot vijf minuten later in te stellen (bijvoorbeeld), en het ‘ werkt perfect Dus … probleem opgelost, maar dat verklaart niet ‘ niet waarom het probleem bestaat. Interessant, interessant, interessant.
- Omdat Apple het mis had. Apple software is veel minder betrouwbaar sinds ze OS X jaarlijks begonnen uit te geven. Ik mis de hogere OS X-secundaire versies (zoals 10.6.8) waar het besturingssysteem keihard was. Je hoeft ‘ gewoon niet meer zon ervaring op te doen.
- Als het ‘ een bug is (waar ik mee akkoord ga with), waarom is niet ‘ t dit nog steeds niet opgelost, vraag ik me af. Heeft iemand hier een radarrapport gemaakt? Wilt u dan alstublieft zijn ID plaatsen? (of / plaats ook op openradar.me)
Antwoord
Tijdens mijn strijd tegen hetzelfde probleem kwam ik dit antwoord op een niet-zo-gerelateerde vraag en besloot het te proberen en het lijkt erop dat werk voor mij.
Vervang delay 5
door do shell script "/bin/sleep 5"
en krijg hetzelfde resultaat.
Opmerkingen
- Bedankt voor het delen! Zoals ik hierboven al zei, ‘ kan dit niet testen omdat, om redenen die voor mij niet logisch zijn, delay 5 op dit moment naar behoren werkt (ik heb net getest het opnieuw een moment geleden). Ik heb geen idee waarom dit soms werkt en soms mislukt.Het ‘ is zo vreemd. Ik heb uiteindelijk een tijdelijke oplossing gebruikt waarbij ik de huidige tijd krijg en deze als een variabele instel, en vervolgens het script pauzeer totdat de tijd variabel is plus één minuut (uiteraard voor een vertraging van 1 minuut). Het ‘ is onhandig, maar het ‘ s werkte maandenlang probleemloos, terwijl er een simpele vertraging met tussenpozen was. Ugh.
- Ik gebruik 10.10.5 en deze oplossing werkt niet en vergrendelt ook het script voor de duur van de slaap.
- @Greg: als het “het script vergrendelt” voor de slaapduur, dan werkt het ‘.
/bin/sleep
wacht op de slaapduur en keert niet terug voordat deze is voltooid. Daarentegen verwerkt AppleScript ‘ s ingebouwdedelay
commando gebruikersinvoergebeurtenissen terwijl het script is gepauzeerd. (Dat is waar de bug zit: als er toetsenbordinvoer van de gebruiker is, gaatdelay
door met de uitvoering van het script voordat de vertragingstijd is verstreken.)
Antwoord
Ik zeg niet dat dit de beste oplossing is, maar het lijkt mijn probleem te hebben opgelost. In plaats van een simpele vertraging te gebruiken, die wordt genegeerd om redenen die ik niet begrijp, ben ik overgeschakeld op het ophalen van de tijd en het herhalen totdat een nieuwe tijd is bereikt (het gebruikt nog steeds een vertraging, maar het maakt niet uit of het de vertraging negeert, aangezien het script niet doorgaat totdat de tijd is bereikt).
# 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
Ik “ben nog steeds stervende om te weten waarom vertraging wordt genegeerd (of dramatisch versneld?! ??), maar dit wordt de klus geklaard, hoe onhandig het ook is.
Opmerkingen
- De ” vertraging ” commando isn ‘ t wordt ” versneld ” , het ‘ s wordt onderbroken. Tijdens het vertragen zit het in een lus om te controleren of er toetsenbordinvoergebeurtenissen zijn, zodat het kan controleren op Command-Period. Blijkbaar verlaat het de vertragingslus ten onrechte wanneer gebruikersinvoer wordt gedetecteerd.
- Interessant! Ik ‘ vind dat het ‘ wordt genegeerd (versneld? Onderbroken?), Zelfs als mijn Mac inactief is, maar dat doe ik niet ‘ weet niet waarom.
- Zodra een gebruikersinvoergebeurtenis in de gebeurteniswachtrij staat, gaat
delay
verder met worden onderbroken totdat iets de gebeurtenissen afhandelt en ze uit de wachtrij verwijdert.
Answer
Ik heb een werk gevonden rond in een Duitse forumbericht . Voeg deze regels toe bovenaan uw script:
use framework "Foundation" use scripting additions current application"s NSThread"s sleepForTimeInterval:1
Reacties
- I ‘ Ik heb problemen met het testen van je antwoord omdat, om welke reden dan ook, de vertraging momenteel werkt zoals verwacht op mijn Mac. Ik heb geen idee waarom. Ik ‘ ben bezig met 10.10.3. Misschien heeft Apple deze bug verholpen? Of misschien is het ‘ slechts een incidenteel probleem dat op dit moment geen ‘ t invloed heeft op mijn Mac. Ugh. Zoals ik hierboven al zei, mijn oplossing is dat Applescript de huidige tijd krijgt en vervolgens uitstelt tot de huidige tijd plus x.
- Ik gebruik ook 10.10.3 en zie het probleem nog steeds. Aangezien niet iedereen het probleem ziet, is het ‘ waarschijnlijk onderbroken of gerelateerd aan software van derden of aan bepaalde voorkeursinstellingen. Wie weet. Trouwens, uw work-around heeft waarschijnlijk het nadeel dat de app tijdens het wachten 100% CPU-tijd gebruikt, terwijl het juiste vertragingsgedrag is om de app gedurende die tijd in de slaapstand te zetten, waardoor er minder stroom wordt verbruikt.
- Ik gebruik 10.10.5 en deze oplossing werkt niet.
- @ThomasTempelmann: het probleem treedt op als er gebruikersinvoer is. Als u niet ‘ klikt of typt terwijl het script wordt uitgevoerd, wordt de bug niet ‘ geactiveerd.
- Merk op dat deze oplossing ervoor zorgt dat de toepassing tijdens de slaap daadwerkelijk vastloopt.
delay
verwerkt gebruikersinvoer terwijl het script is gepauzeerd, zodat u bijvoorbeeld nog steeds kunt communiceren met menus en vensters.
Antwoord
carzyj had wat ik beschouw als het beste antwoord, maar in combinatie met de methode van Chris Page krijg je:
on delay duration do shell script "/bin/sleep " & duration end delay
Je kunt “on delay” tot en met “end delay” een opmerking plaatsen om terug te keren naar de oorspronkelijke vertraging.
Opmerkingen
- I maakte ook een soortgelijke codewijziging voordat ik dit zag. Ik gebruik 10.10.5 en deze oplossing werkt niet en vergrendelt ook het script voor de duur van de slaap.
Antwoord
dit is een aanpassing aan @ chris-page solution
Het lijkt een evenwicht te zijn tussen reactievermogen en het nauwkeurig vastleggen van de vertraging.
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
Maar in plaats van Applescript te vertellen dat het de totale duur moet uitstellen, vertellen we het gewoon om een fractie van de duur uit te stellen. als de periode korter is dan wat appel toestaat (1/60 van een seconde), laten we het dan gewoon op die delta zetten. Dat we wat reactievermogen kunnen behouden, maar toch accuraat zijn. het vermoeden is dat vertraging soms niet werk zodat de repeat while-lus de thread vergrendeld houdt, maar in successcenarios willen we dat de delay-delta kort is, zodat het proces nog steeds kan worden onderbroken.
Comments
- Het verkorten van de gevraagde vertraging is niet nodig en kan het script alleen maar langzamer laten werken en meer CPU verbruiken tijdens het wachten. Mijn versie roept alleen vertraging op totdat de volledige gewenste duur is verstreken, waardoor
delay
zo lang mogelijk kan wachten voordat de uitvoering wordt voortgezet. - Merk op dat sinds dit antwoord is gepost, heb ik mijn code bijgewerkt om
delay endTime - (current date)
te gebruiken in plaats vandelay duration
, wat ervoor zorgt dat ifdelay
wordt niet ‘ t onderbroken het zal ‘ het script niet langer pauzeren dan de oorspronkelijk aangevraagde tijd , wat u wellicht probeerde aan te pakken met dit antwoord.
Antwoord
Dus, om te zeggen alles bij elkaar, denk ik dat Chris dit bedoelt:
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