¿Cómo puedo reiniciar una aplicación actualmente en ejecución con AppleScript?

4

He creado una aplicación con una acción "Ejecutar AppleScript" en Automator.

He creado un Servicio en Automator que lanza la aplicación mencionada anteriormente.

El servicio se activa mediante un método abreviado de teclado, asignado en Preferencias del sistema

La aplicación presenta una serie de diálogos al usuario. Me gustaría dar al usuario la opción de reiniciar la aplicación completa a mitad de la aplicación. Por ejemplo, suponga que la siguiente línea es la línea 100 del código:

set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Start over", "No", "Yes"})

   if buttonChoice is "Start over" then     
      <this is where I need your help, Ask Different>
   end if

Cuando digo "reiniciar" o "empezar de nuevo", quiero decir que quiero devolver al usuario al cuadro de diálogo inicial de la aplicación, es decir, la primera línea de código de la aplicación.

¿Se puede hacer esto usando AppleScript?

Si es necesario, esta es la ubicación del archivo de la aplicación:

  

/ Aplicaciones / Mis aplicaciones / Mi Log.app

    
pregunta rubik's sphere 23.01.2017 - 06:47

3 respuestas

2

El siguiente código asume que la acción Ejecutar AppleScript comienza con un comando on run sin ningún lista , por ejemplo, {input, parameters} y, por lo tanto, finaliza el script con end run :

on run

    (*
            This comment represents the e.g. previous 99 lines of code.
        *)

    set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Start over", "No", "Yes"})
    try
        if buttonChoice is "Start over" then
            return on run
        end if
    end try

    (*
            This comment represents the rest of the code in the script.
        *)

end run

Tenga en cuenta que probé esto en macOS Sierra 10.12 y, si bien parece que comienza de nuevo, porque si presiona el botón "Comenzar de nuevo" se repite hasta que seleccione otra opción, no estoy seguro de que esta sea la mejor manera de implementar esto Lo digo porque no conozco la estructura y la codificación del resto del script y puede marcar la diferencia junto con el hecho de que, al probar otros códigos en cada lado En este punto, pude bloquear la aplicación dependiendo de lo que ocurría si realizaba un bucle más de una vez.

Dicho esto, estoy ofreciendo esto como algo para probar antes de implementarlo en el código final.

Sugeriría simplemente permitir que el usuario finalice la aplicación con un mensaje para que se reinicie manualmente presionando la combinación de teclas para activar el servicio que inicia la aplicación al implementar un bucle como este.

    
respondido por el user3439894 23.01.2017 - 23:13
1

Actualización:

Comencé con la solución de user3439894 como mi base, pero tuve que hacer un par de modificaciones para perfeccionar la función de "reinicio" de mi aplicación (como lo recomendó user3439894).

Al principio, cuando copié directamente la solución, tenía un problema por el cual el código se ejecutaría una vez más después de que se completara la ejecución reiniciada. Pero, por prueba y error, logré intuir una solución.

Esto es lo que hice para que funcione:

Puse la siguiente línea antes de la primera línea del cuerpo principal de mi código:

try

y al final de mi cuerpo principal de código, coloco:

on error errStr number errorNumber
end try

De acuerdo con las instrucciones del usuario3439894, también tuve que eliminar la línea return input predeterminada de esta ubicación (y de todos modos no tenía necesidad de return input en esta aplicación).

Luego, después de cada diálogo en el que quería que se presentara al usuario con la opción de volver a comenzar en ese diálogo, pongo:

if buttonChoice is "Start over" then
    return on run
end if

Siguiendo estos pasos, la función de "reinicio" funciona perfectamente! No se repite una cantidad extra de veces al final, ni tampoco presenta al usuario algún error. También puedo hacer un bucle de la aplicación varias veces, si así lo deseo, sin error ni problema.

Incluso funciona perfectamente cuando los diálogos están ubicados en subrutinas. Tenga en cuenta que mis subrutinas están no dentro del bloque try .

¿Qué sucede cuando necesitas usar input en tu AppleScript?

Me las arreglé para descubrir una solución. Simplemente coloque el código de reinicio dentro de una subrutina:

on run {input, parameters}
    restartSubroutine()
    return input
end run

on restartSubroutine()
    set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Start over", "No", "Yes"})

    try
        if buttonChoice is "Start over" then
            return on run restartSubroutine()
            (*
            The following lines work as well:
            return on restartSubroutine()
            return run restartSubroutine()
            *)
        end if
    end try
end restartSubroutine

Por supuesto, la función de reinicio solo lo llevará de regreso al principio de esa subrutina, no a la primera línea del cuerpo principal. Pero, si no necesita hacer referencia a input hasta el final de su secuencia de comandos, esto puede funcionar para que pueda tener un botón de reinicio funcional hasta el momento en que necesite input .

Editar:

Acabo de descubrir una solución aún mejor:

on run {input, parameters}
    restartSubroutine(input)
    return input
end run

on restartSubroutine(input)
    set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Start over", "No", "Yes"})

    if buttonChoice is "Start over" then
        return restartSubroutine(input)
    end if      
end restartSubroutine

Si envía el input a una subrutina, entonces puede tener una función de reinicio mientras tiene acceso a los contenidos de input . Ganar-ganar.

    
respondido por el rubik's sphere 03.02.2017 - 02:46
0

He descubierto otro método para reiniciar un AppleScript.

Este método no es "mejor" que los otros métodos que se han proporcionado; es simplemente una forma más de acercarse a las cosas. Aquí le mostramos cómo puede reiniciar un archivo .scpt en AppleScript:

if buttonChoice is "Start over" then
    run script "/Users/Me/Desktop/My script.scpt"
    error number -128 (* user cancelled *)
end if

O, alternativamente:

if buttonChoice is "Start over" then
    run script (path to me)
    error number -128 (* user cancelled *)
end if

Este código simplemente crea otra instancia del archivo .scpt de AppleScript que se ejecuta actualmente, y luego cierra la instancia actual.

Aprendí sobre run script a partir de un comentario del usuario Camelot en la siguiente página web:

Llame a otro AppleScript | Comunidades de Apple

Con la misma premisa subyacente, si desea reiniciar un archivo .app usando AppleScript, use esto:

if buttonChoice is "Start over" then
    do shell script "open -n " & quoted form of "/Users/Me/Desktop/My app.app"
    error number -128 (* user cancelled *)
end if

O, alternativamente:

if buttonChoice is "Start over" then
    do shell script "open -n " & (quoted form of (POSIX path of (path to me)))
    error number -128 (* user cancelled *)
end if

El -n permite abrir una nueva instancia de la aplicación, incluso si ya se está ejecutando una instancia de esta aplicación. El -n es necesario porque, prácticamente hablando, la aplicación AppleScript se cierra técnicamente después de que se haya creado la segunda instancia, aunque puede que este no sea el caso basado en lo que se ve en su pantalla.

¿Cuándo debería uno usar este método de reinicio?

Esto va a ser un poco confuso, así que ten paciencia ...

Tengo un archivo .scpt de AppleScript que se ejecuta automáticamente cuando mi computadora se despierta. (Uso SleepWatcher para lograr esto.)

Este archivo .scpt llama a una subrutina específica de un archivo .scpt diferente; omite toda la secuencia de comandos y solo ejecuta el código que se encuentra en una subrutina específica. (Para lograr esto, yo uso el método descrito aquí .)

Este segundo archivo .scpt está repleto de botones "Comenzar de nuevo" en casi todos los cuadros de diálogo, empleando:

return on run

para lograr el efecto de reinicio. (Este método de reinicio se proporcionó en una respuesta anterior a esta pregunta).

Ahora, el problema es que, mientras mi primer archivo .scpt se reinicia con éxito , el segundo archivo .scpt cuando se usa return on run en el segundo archivo .scpt, una vez que el script ha finalizado , se presenta al usuario un cuadro de diálogo que contiene el siguiente error:

  

«script» no entiende la "devolución"

Para ser justos, este error tiene sentido; el primer archivo .scpt no puede comprender completamente el significado de return , porque nunca ejecutó realmente el otro script. Solo estaba ejecutando una subrutina del otro script.

Este error me molestó. Así que, jugué un poco más con el código y aprendí sobre run script . El tipo específico de escenario que acabo de explicar es donde realmente brilla el método run script restart.

El método simple run script salva el día: reinicia el segundo archivo .scpt y sin tener que invocar el comando return en el proceso. Por lo tanto, este método está completamente libre de errores, incluso cuando se ejecuta fuera de su código circundante más grande. Este es el único método en esta página que puede hacer esto, ya que los otros métodos dependen de return .

    
respondido por el rubik's sphere 09.03.2017 - 04:39

Lea otras preguntas en las etiquetas