Error de la barra de progreso de AppleScript: ¿Cómo evitar que el diálogo de progreso se detenga?

6

El error:

Cuando diálogo de progreso de AppleScript se realiza mediante un diálogo, el el diálogo de progreso aún persiste, aunque todos los pasos del progreso se hayan completado y la barra de progreso esté llena. Permanecerá hasta que el script haya sido cancelado, hasta que el script haya finalizado, o hasta que no haya diálogos adicionales en el script.

No se puede observar este error al ejecutar el código desde Script Editor.app, ya que, en el Editor de secuencias de comandos, no aparecerá un cuadro de diálogo de progreso. En su lugar, un medidor de progreso en forma circular se integra en la parte inferior de la ventana del script.

Cómo reproducir el error:

Guarde el siguiente AppleScript código como un archivo .app:

(El archivo debe ser un archivo .app, ya que los archivos .scpt no pueden mostrar diálogos de progreso).

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."

Al iniciar la aplicación, verá lo siguiente:

La pregunta:

¿Existe una solución alternativa para forzar que el cuadro de diálogo de progreso se cierre una vez que esté completo, de modo que se puedan colocar cuadros de diálogo adicionales después del cuadro de diálogo de progreso, sin que el cuadro de diálogo de progreso siga visible?

Lo que he probado:

Intenté abordar el problema interpretando el diálogo de progreso simplemente como una "ventana" de la aplicación.

Si ejecuta el siguiente código en un archivo AppleScript separado, mientras que los dos cuadros de diálogo de ProgressBarTest.app están en la pantalla (como se muestra en la captura de pantalla anterior):

tell application "System Events"
    set allWindows to name of window of processes whose visible is true
end tell 

return allWindows

aprenderá que ProgressBarTest.app tiene 2 "ventanas" abiertas. Los títulos de estas ventanas son:

{"", "ProgressBarTest.app"}

La primera ventana de esta lista se refiere al diálogo display dialog . La segunda ventana de esta lista, titulada ProgressBarTest.app , es el diálogo de progreso.

Luego intenté cerrar la "ventana" del cuadro de diálogo de progreso utilizando AppleScript (como se puede hacer con cualquier ventana de aplicación estándar). Pero, el siguiente código:

tell application "System Events" to tell process "ProgressBarTest.app"
    if exists window "ProgressBarTest.app" then
        close window "ProgressBarTest.app"
    end if
end tell

le dará al usuario un error. El texto de este diálogo de error es:

  

Error de secuencia de comandos

     

Los eventos del sistema obtuvieron un error: la ventana "ProgressBarTest.app" del proceso "ProgressBarTest.app" no comprende el mensaje "cerrar".

Pronto me di cuenta de que, si su pantalla tiene el mismo punto de vista que el de la captura de pantalla anterior, ni siquiera puede cerrar manualmente el cuadro de diálogo de progreso. Esto se debe a que el diálogo display dialog tiene prioridad sobre el diálogo de progreso; el cuadro de diálogo display dialog "se pone gris" (es decir, deshabilita) todos los botones en el cuadro de diálogo de progreso.

Entonces, para tener en cuenta esto, en el código ProgressBarTest.app, agregué un delay 5 directamente sobre la línea display dialog "The progress dialog should be gone at this point." . Quería ver si podía cerrar con éxito el diálogo de progreso, si el diálogo de progreso era el único diálogo activo de la aplicación.

Probé el siguiente código:

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

En el código anterior, button 1 se refiere al botón Stop que se encuentra en el cuadro de diálogo de progreso. (Alternativamente, puede usar button -4 o button 0 para referirse a este mismo botón).

¡La buena noticia es que este código se cerró con éxito fuera del diálogo de progreso!

La mala noticia, sin embargo, es que cuando se presiona el botón Stop del cuadro de diálogo de progreso, en lugar de que solo se cierre el cuadro de diálogo de progreso, se cancela el script completo . Esto es obviamente indeseable.

La raíz del problema es que el cuadro de diálogo de progreso no contiene una "x" roja; el botón circular que está más a la izquierda en la barra superior de este cuadro de diálogo siempre aparece en gris. En otras palabras, no hay forma de cerrar el cuadro de diálogo de progreso manualmente, sin terminar también prematuramente el script.

Entonces, este problema es más difícil de resolver de lo que pensaba.

Parece que mi resultado deseado es imposible de lograr.

OS X El Capitan, versión 10.11.6.

pregunta rubik's sphere 29.05.2017 - 22:20

1 respuesta

4

Funciona para mí en la última versión de Sierra

SOLUCIÓN 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

Estaesunaformadeejecutaralgunosbuclesderepeticiónantesdequesecierrelasecuenciadecomandos

setnto5setprogresstotalstepstonsetprogressdescriptionto"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

ACTUALIZAR

SOLUCIÓN 2

Trabajando en uno de mis propios proyectos, tuve uno de esos "EUREKA!" momentos Este es un enfoque completamente diferente al de mi código en la SOLUCIÓN 1. El enfoque aquí fue envolver la mayor parte de mi código en objetos de script o controladores, y luego llamar a esos objetos según sea necesario. En esta solución, guardé este script como una aplicación abierta, con controladores explícitos de ejecución y inactivos. Parte del código se ejecuta cuando se inicia la aplicación, pero la mayoría de los comandos realmente ocurren dentro del controlador de inactividad.

Creo que esta solución es más prometedora que la SOLUCIÓN 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

    
respondido por el wch1zpink 30.05.2017 - 06:41

Lea otras preguntas en las etiquetas