AppleScript “gecikme” komutu Yosemite'a geçildiğinden beri çalışmıyor


10

Not: ile ilgili sorun delayOS X 10.11 El Capitan'da düzeltildi.

Yosemite sürümüne geçtiğimden beri, gecikmeleri kullanan Apple uygulamaları çalışmıyor. Bunu nasıl düzeltebilirim?

İşte kolay bir örnek uğruna dünyanın en basit Applescript'i:

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

Bu işlemin tamamlanması 30 saniye sürmelidir. Komut Dosyası Düzenleyicisi'nde (eski adıyla Applescript Düzenleyicisi) çalıştırırsam, tamamlanması 30 saniye sürer. Ancak bu komut dosyasını bir uygulama olarak kaydedersem, uygulamayı başlattığımda gecikmeler yok sayılır ve uygulamanın tamamlanması bir saniyenin bir kısmını alır.

Applescript'i bir sonraki adıma geçmeden önce belirli bir süre gecikmeye nasıl zorlayabilirim? Bu bir Yosemite aksaklığı mı? Güvenilir bir geçici çözüm var mı?


Bu benim Mac'te (10.10.1) beklendiği gibi çalışıyor
markhunte

Benim üzerinde çalışmamasına neden olan bir fikrin var mı? Açıklığa kavuşturmak için: Komut Dosyası Düzenleyicisi'nde çalışır, ancak komut dosyasını bir uygulama olarak kaydedip uygulamayı başlatırsam, gecikmeler yok sayılır. Bu en garip şey.
2oh1

Aynı sorun 10.10.3'te
Thomas Tempelmann


1
Bu sorun OS X 10.11 El Capitan'da giderilmiştir.
Chris Page

Yanıtlar:


7

Not: ile ilgili sorun delayOS X 10.11 El Capitan'da düzeltildi.

@ 2oh1, cevabınızda doğru temel fikre sahipsiniz, ancak tam ve doğru bir cevap:

Bu sorunu geçici olarak çözmek için tek makul yol, devam etmeden önce istenen sürenin geçmesini sağlayan bir döngü içinde "gecikme" yi çağırmaktır. Bunu yapmanın en iyi yolu özel bir işleyici ile "gecikmeyi" geçersiz kılmaktır:

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

Bu, komut dosyanızın geri kalanını değiştirmeden bırakmanıza olanak tanır ve normal olarak "gecikme" kullanabilirsiniz, örn.

delay 5
display alert "I like cake!"

[NOT: Normal olarak, özel işleyici yerleşik "gecikme" yi çağırmak için "gecikme süresine devam et" kullanır, ancak bunun Script Editor'da çalışmasına rağmen bir uygulama içinde kullanıldığında bir hata döndürdüğünü gördüm ("Can" t gecikmeye devam. (-1708) ”). Bu soruna, doğrudan AppleScript'e oraya ulaşmak için "devam" kullanmak yerine gecikme komutunu işlemesini söyleyerek çalıştım.]

Sorun, delaykomut dosyasını duraklatırken kullanıcı girişini işler, böylece bir uygulama tarafından görüntülenen menülere veya pencerelere tıklayabilirsiniz ve kullanıcı girişinin delaykomut dosyası yürütmeye devam etmeden önce tam süreyi beklememesine neden olan bir hata (10.11'de düzeltildi) . Uygulama ile etkileşime girmezseniz, delaydüzgün çalışır.


Tüm bunlar bir hata mı, yoksa Yosemite ile bu şekilde çalışmanın gecikmesinin bir nedeni var mı?
2oh1

Gecikmenin gecikmediği bir hatadır.
Chris Page

Bu çok tuhaf. Geçen gece gecikme kullanan bir el yazısıyla uğraşıyordum ve aniden gecikme tekrar düzgün çalışıyordu. Hatanın giderildiğini varsaydım. Bir saat sonra, hiçbir şey değişmemiş olsa da, hata geri döndü. Gerçekten şaşkınım. Yine de önemli değil. Ben beş dakika sonra (örneğin) kadar zaman ve gecikme ayarlamak için bir değişken kullanıyorum ve mükemmel çalışıyor. Yani ... problem çözüldü, ama bu sorunun neden var olduğunu açıklamıyor. İlginç, ilginç, ilginç.
2oh1

1
Çünkü Apple kandı. Apple yazılımı, OS X'i her yıl piyasaya sürmeye başladıkları için çok daha az güvenilirdir. İşletim sisteminin kaya gibi sağlam olduğu daha yüksek OS X küçük sürümlerini (10.6.8 gibi) özlüyorum. Artık böyle bir deneyim elde edemezsiniz.
William T Froggard

Eğer bir hata ise (ki buna katılıyorum), neden hala sabit değil, merak ediyorum. Burada bir radar raporu var mı? O zaman lütfen kimliğini gönderir misiniz? (veya / openradar.me'de de yayın)
Thomas Tempelmann

5

Aynı problemle savaşırken, bu kadar alakalı olmayan bir sorunun cevabına rastladım ve denemeye karar verdim ve bu benim için işe yarıyor gibi görünüyor.

Basitçe yerine delay 5sahip do shell script "/bin/sleep 5"ve aynı sonucu alırsınız.


Paylaşım için teşekkürler! Yukarıda daha önce de söylediğim gibi, bunu test edemiyorum çünkü bana mantıklı gelmeyen nedenlerden dolayı, gecikme 5 şu anda benim için olması gerektiği gibi çalışıyor (bir an önce tekrar test ettim). Bunun neden bazen işe yarayıp bazen başarısız olduğuna dair hiçbir fikrim yok. Bu çok tuhaf. Geçerli saati almak ve bir değişken olarak ayarlamak bir geçici çözüm kullanarak sona erdi ve sonra zaman değişken artı bir dakika (1 dakikalık bir gecikme için, tabii ki) olana kadar komut dosyası duraklatmak. Çok karmaşık, ama aylarca kusursuz bir şekilde çalıştı, ancak basit bir gecikme aralıklı oldu. Ugh.
2oh1

10.10.5 çalıştırıyorum ve bu çözüm çalışmıyor ve ayrıca uyku süresi için komut dosyası kilitler
Greg

@Greg: Uyku süresi boyunca “betiği kilitlerse” çalışır. /bin/sleepuyku süresini bekler ve tamamlanana kadar geri dönmez. Buna karşılık, AppleScript'in yerleşik delaykomutu, komut dosyası duraklatılmış durumdayken kullanıcı giriş olaylarını işler. (Bu, hatanın yattığı yerdir: kullanıcı klavye girişi varsa delay, gecikme süresi tamamlanmadan kod yürütmeye devam eder.)
Chris Page

3

Bunun en iyi çözüm olduğunu söylemiyorum, ama sorunumu çözmüş görünüyor. Anlamadığım nedenlerle göz ardı edilen basit bir gecikme kullanmak yerine, yeni bir zamana ulaşana kadar zamanı almaya ve döngüye geçtim (hala bir gecikme kullanıyor, ancak görmezden gelip gelmediği önemli değil betiğin zamana ulaşılıncaya kadar devam etmemesi nedeniyle).

# 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

Hala gecikmenin neden göz ardı edildiğini (veya dramatik bir şekilde hızlandırıldığını?! ??) bilmek için can atıyorum, ama bu işi olduğu gibi beceriksiz yapıyor.


"Gecikme" komutu "hızlandırılmıyor", kesiliyor. Gecikme sırasında, herhangi bir klavye giriş olayı olup olmadığını kontrol eden bir döngüde oturur, böylece Komut Dönemi'ni kontrol edebilir. Görünüşe göre herhangi bir kullanıcı girişi tespit edildiğinde gecikme döngüsünden yanlış çıkıyor.
Chris Page

İlginç! Mac'im boştayken bile göz ardı edildiğini (hızlandırıldı mı? Kesildi?) Buluyorum, ama nedenini bilmiyorum.
15.03.2015

Bir kullanıcı girdi olayı olay kuyruğuna girdikten sonra, bir delayşey olayları işleyip sıradan kaldırana kadar kesilmeye devam edilecektir.
Chris Page

2

Bir Alman forum gönderisinde bir çözüm buldum . Bu satırları komut dosyanızın üstüne ekleyin:

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

Cevabınızı test etmekte sorun yaşıyorum çünkü herhangi bir nedenle gecikme şu anda Mac bilgisayarımda beklendiği gibi çalışıyor. Neden olduğuna dair hiçbir fikrim yok. Koşuyorum 10.10.3. Belki Apple bu hatayı düzeltti? Ya da, belki de şu anda Mac'imi etkilemeyen sadece aralıklı bir sorun. Ugh. Yukarıda söylediğim gibi, benim geçici çözüm Applescript geçerli saati almak ve daha sonra şimdiki zaman artı x kadar geciktiriyor.
2oh1

Ben de 10.10.3 kullanıyorum ve hala sorunu görüyorum. Herkes sorunu görmediğinden, büyük olasılıkla kesintili veya üçüncü taraf yazılımları veya belirli tercih ayarlarıyla ilgilidir. Kim bilir. BTW, geçici çözümünüz, uygulamanın beklerken% 100 CPU zamanı kullanmaya devam etmesinin dezavantajına sahipken, uygun gecikme davranışı, uygulamayı bu süre boyunca uyutmak, böylece daha az güç kullanmaktır.
Thomas Tempelmann

10.10.5 çalıştırıyorum ve bu çözüm çalışmıyor.
Greg

@ThomasTempelmann: Sorun, kullanıcı girişi olduğunda ortaya çıkar. Komut dosyası çalışırken tıklamaz veya yazmazsanız hata tetiklenmez.
Chris Page

Bu çözümün uygulamanın uyku süresi boyunca gerçekten donmasına neden olduğunu unutmayın. delaykomut dosyası duraklatıldığında kullanıcı girişini işler; böylece, örneğin menüler ve pencerelerle etkileşimde bulunabilirsiniz.
Chris Page

0

carzyj en iyi yanıtı düşündüğüm şey vardı, ama Chris Page yöntemi ile birleştirildiğinde, elde edersiniz:

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

Orijinal gecikmeye geri dönmek için "gecikmeli" ile "bitiş gecikmesi" arasında yorum yapabilirsiniz.


Bunu görmeden önce de benzer bir kod değişikliği yaptım. 10.10.5 çalıştırıyorum ve bu çözüm çalışmıyor ve ayrıca uyku süresi için komut dosyası kilitler.
Greg

0

bu @ chris-page çözümünde yapılan bir değişikliktir

Duyarlılık ile gecikmeyi doğru bir şekilde yakalama arasında bir denge gibi görünüyor.

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

Ancak, Applescript'e toplam süre için gecikmesini söylemektense, sürenin kesirli bir süresi için gecikmesini söylemekteyiz. Eğer süre elmanın izin verdiğinden daha azsa (saniyenin 1 / 60'ı), o zaman onu sadece deltaya ayarlayalım. Bazı duyarlılıkları koruyabileceğimiz halde yine de doğru olabiliriz. şüphe bazen gecikme işe yaramaz, bu yüzden döngü tekrarlama iş parçacığını kilitli tutar, ancak başarı senaryolarında, gecikme deltasının kısa olmasını isteriz, böylece işlem hala kesilebilir


İstenen gecikmeyi kısaltmak gereksizdir ve betiğin daha yavaş çalışmasını sağlayabilir ve beklerken daha fazla CPU tüketebilir. Benim sürümüm sadece istenen süre geçene kadar gecikmeyi çağırır ve delayyürütmeye devam etmeden önce olabildiğince gecikmeyi sağlar.
Chris Page

Bu cevap yayınlanmıştır beri, kullandığım için kodumu güncellenen geldiğini hatırlatırız delay endTime - (current date)yerine delay durationeğer hangi teminat altın, delay gelmez kesintiye olsun size çalıştıkları şey olmuş olabilir ki, artık başlangıçta istediği zamandan daha senaryoyu duraklama olmayacaktır bu cevap ile adres.
Chris Page

0

Yani, hepsini bir araya getirmek için, Chris'in şu anlama geldiğine inanıyorum:

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.