Wenn auf den Fortschrittsdialog von AppleScript ein Dialog folgt, bleibt der Fortschrittsdialog bestehen – obwohl alle Fortschrittsschritte abgeschlossen wurden und der Fortschrittsbalken voll ist. Es bleibt bestehen, bis das Skript abgebrochen wurde, bis das Skript abgeschlossen ist oder bis keine weiteren Dialogfelder im Skript vorhanden sind.
Dieser Fehler kann nicht beobachtet werden, während der Code in Script Editor.app ausgeführt wird, da im Script Editor kein Fortschrittsdialogfeld angezeigt wird. Stattdessen ist unten im Skriptfenster eine tortenförmige Fortschrittsanzeige integriert.
Speichern Sie den folgenden AppleScript -Code als .app-Datei:
(Die Datei muss eine .app-Datei sein, da .scpt-Dateien keine Fortschrittsdialoge anzeigen können.)
set n to 5
set progress total steps to n
set progress description to "Script Progress"
set progress additional description to "Additional description"
repeat with i from 1 to n
delay 0.1
set progress completed steps to i
end repeat
display dialog "The progress dialog should be gone at this point."
Nach dem Start der Anwendung sehen Sie Folgendes:
Gibt es eine Problemumgehung, um das Schließen des Fortschrittsdialogs zu erzwingen, sobald er abgeschlossen ist, sodass zusätzliche Dialoge nach dem Fortschrittsdialog platziert werden können, ohne dass der Fortschrittsdialog noch sichtbar ist?
Ich habe versucht, das Problem anzugehen, indem ich den Fortschrittsdialog einfach als "Fenster" der App interpretierte.
Wenn Sie den folgenden Code in einer separaten AppleScript-Datei ausführen, während beide Dialoge von ProgressBarTest.app auf dem Bildschirm angezeigt werden (wie im obigen Screenshot):
tell application "System Events"
set allWindows to name of window of processes whose visible is true
end tell
return allWindows
Sie werden erfahren, dass ProgressBarTest.app 2 offene "Fenster" hat. Die Titel dieser Fenster lauten:
{"", "ProgressBarTest.app"}
Das erste Fenster in dieser Liste bezieht sich auf den display dialog
Dialog. Das zweite Fenster in dieser Liste mit dem Titel ProgressBarTest.app
ist der Fortschrittsdialog.
Ich habe dann versucht, dieses Fortschrittsdialog-"Fenster" mit AppleScript zu schließen (wie man es für jedes Standardanwendungsfenster tun kann). Aber folgender Code:
tell application "System Events" to tell process "ProgressBarTest.app"
if exists window "ProgressBarTest.app" then
close window "ProgressBarTest.app"
end if
end tell
gibt dem Benutzer einen Fehler. Der Text dieses Fehlerdialogs lautet:
Skriptfehler
Bei Systemereignissen ist ein Fehler aufgetreten: Das Fenster „ProgressBarTest.app“ des Prozesses „ProgressBarTest.app“ versteht die Meldung „Schließen“ nicht.
Mir wurde schnell klar, dass Sie den Fortschrittsdialog nicht einmal manuell schließen können, wenn Ihr Bildschirm den gleichen Standpunkt wie der des obigen Screenshots hat. Dies liegt daran, dass der display dialog
Dialog Vorrang vor dem Fortschrittsdialog hat; der display dialog
Dialog "graut aus" (dh deaktiviert) alle Schaltflächen im Fortschrittsdialog.
Um dies zu berücksichtigen, habe ich im Code von ProgressBarTest.app ein delay 5
direkt über der display dialog "The progress dialog should be gone at this point."
Zeile hinzugefügt. Ich wollte sehen, ob ich den Fortschrittsdialog erfolgreich schließen kann, wenn der Fortschrittsdialog der einzige aktive Dialog der Anwendung ist.
Ich habe folgenden Code ausprobiert:
tell application "System Events" to tell process "ProgressBarTest.app"
if exists window "ProgressBarTest.app" then
click button 1 of window "ProgressBarTest.app"
end if
end tell
Bezieht sich im obigen Code button 1
auf die StopSchaltfläche, die sich im Fortschrittsdialog befindet. (Sie können alternativ button -4
oder verwenden button 0
, um auf dieselbe Schaltfläche zu verweisen.)
Die gute Nachricht ist, dass dieser Code den Fortschrittsdialog erfolgreich geschlossen hat!
Die schlechte Nachricht ist jedoch, dass beim Drücken der StopSchaltfläche des Fortschrittsdialogs nicht nur der Fortschrittsdialog geschlossen wird, sondern das gesamte Skript abgebrochen wird. Dies ist offensichtlich unerwünscht.
Die Wurzel des Problems liegt darin, dass der Fortschrittsdialog kein rotes „x“ enthält; Die kreisförmige Schaltfläche ganz links in der oberen Leiste dieses Dialogfelds ist immer ausgegraut. Mit anderen Worten, es gibt keine Möglichkeit, den Fortschrittsdialog manuell zu schließen, ohne auch das Skript vorzeitig zu beenden.
Dieses Problem ist also schwieriger zu lösen, als ich dachte.
Es scheint, dass mein gewünschtes Ergebnis unmöglich zu erreichen ist.
OS X El Capitan, Version 10.11.6.
Funktioniert für mich auf der neuesten Version von macOS Big Sur
AKTUALISIEREN
BESTE LÖSUNG
Wenn Sie den display dialog
Befehl innerhalb von platzieren und den Befehl dann um diesen Befehl System Events tell block
wickeln , führt der seine Aufgabe aus, ohne darauf zu warten, dass das Fenster geschlossen wird.ignoring application responses
display dialog
progress indicator
display dialog
Der ignoring application responses
Befehl funktioniert nur, wenn er innerhalb einer Anwendung platziert wirdtell block
set n to 50
set progress total steps to n
set progress description to "Script Progress"
set progress additional description to "Additional description"
repeat with i from 1 to n
delay 0.1
set progress completed steps to i
end repeat
tell application "System Events"
activate
ignoring application responses
display dialog "The progress dialog should be gone at this point."
end ignoring
end tell
ALTE LÖSUNG 1
set n to 5
set progress total steps to n
set progress description to "Script Progress"
set progress additional description to "Additional description"
repeat with i from 1 to n
delay 0.1
set progress completed steps to i
end repeat
return
quit
on quit
activate
display dialog "The progress dialog should be gone at this point."
continue quit -- allows the script to quit
end quit
Hier ist eine Möglichkeit, einige Wiederholungsschleifen auszuführen, bevor das Skript beendet wird
set n to 5
set progress total steps to n
set progress description to "Script Progress"
set progress additional description to "Additional description"
repeat with i from 1 to n
delay 0.1
set progress completed steps to i
end repeat
return
quit
on quit
activate
display dialog "The progress dialog should be gone at this point."
repeat 5 times
my get_my_IP()
my screenCaptureToDesktop()
delay 1
end repeat
continue quit -- allows the script to quit
end quit
on get_my_IP()
activate
tell current application to display dialog (do shell script "curl ifconfig.co") with icon 2 buttons "OK" default button 1 with title "Your Current IP Address Is.." giving up after 5 -- "curl ifconfig.io" -- alternate
end get_my_IP
on screenCaptureToDesktop()
do shell script "/usr/sbin/screencapture \"" & ¬
POSIX path of (path to desktop as string) & ¬
"Screen Shot " & (current date) & ".png\""
end screenCaptureToDesktop
ALTE LÖSUNG 2
Als ich an einem meiner eigenen Projekte arbeitete, hatte ich eines dieser "EUREKA!" Momente. Hier ist ein völlig anderer Ansatz als mein Code in LÖSUNG 1. Der Ansatz hier bestand darin, den größten Teil meines Codes in Skriptobjekte oder Handler einzuschließen und diese Objekte dann nach Bedarf aufzurufen. In dieser Lösung habe ich dieses Skript als geöffnet bleibende Anwendung mit expliziten Run- und Idle-Handlern gespeichert. Ein Teil des Codes wird ausgeführt, wenn die Anwendung gestartet wird, aber die meisten Befehle werden tatsächlich innerhalb des Idle-Handlers ausgeführt.
Ich denke, diese Lösung ist vielversprechender als LÖSUNG 1.
global allFiles, thisFile, theFileCount, ProgressBar, mainFolder, backupFolder, theDate
on run
run ProgressBar
end run
on idle
delay 0.2
activate
set theButton to button returned of (display dialog ¬
"The progress dialog should be gone at this point." buttons {"QUIT", "CONTINUE"} ¬
default button ¬
"CONTINUE" with title ¬
"BACKUP UTILITY" with icon 0 ¬
giving up after 10)
if theButton = "QUIT" then
quit
else if theButton = "" then
quit
else if theButton = "CONTINUE" then
try
run ProgressBar
end try
end if
return 1
end idle
on quit
-- Executed when the script quits
continue quit -- allows the script to quit
end quit
script ProgressBar
set mainFolder to choose folder with prompt ¬
"PLEASE CHOOSE YOUR SOURCE FOLDER TO BACKUP"
set backupFolder to choose folder with prompt ¬
"PLEASE CHOOSE YOUR BACKUP DESTINATION FOLDER"
set theDate to (current date) - (14 * days)
tell application "Finder"
set allFiles to entire contents of folder mainFolder as alias list
end tell
set theFileCount to count of allFiles
set progress total steps to theFileCount
set progress completed steps to 0
set progress description to "Processing Files..."
set progress additional description to "Preparing to process."
repeat with theName from 1 to number of items in allFiles
set this_item to item theName of allFiles
tell application "Finder"
duplicate this_item to backupFolder ¬
with replacing
end tell
set progress additional description to ¬
"Duplicating File " & theName & " of " & theFileCount & ¬
" to folder " & backupFolder
set progress completed steps to theName
end repeat
-- Reset the progress information
set progress total steps to 0
set progress completed steps to 0
set progress description to ""
set progress additional description to ""
end script
on quit
Unterprogramm zu verlassen, sobald es einmal eingegeben wurde, ist es beispielsweise nicht mehr möglich, das gesamte Skript in eine repeat
Schleife zu packen. Auf jeden Fall glaube ich nicht, dass ich eine bessere Problemumgehung als Ihre Methode finden werde! Danke!ignoring application responses
auskommentiert , erneut gespeichert und ausgeführt hatte, um die Erlaubnis erneut zu erteilen und dann den Block auskommentieren, erneut speichern, erneut ausführen und erneut die Erlaubnis geben, und erst nach all dem Tanz würde der Anzeigedialog normal angezeigt. 2. Die Verwendung von Finder ist ärgerlich, da es jedes offene Finder - Fenster nach vorne
bringt .System Events
Iwan X
Rubiks Sphäre
wch1zpink