Como posso reiniciair um aplicativo atualmente em execução com o AppleScript?

Criei um aplicativo com uma ação "Executair AppleScript" no Automator.

Criei um Serviço no Automator que lança o aplicativo acima mencionado.

O Serviço é acionado por um atalho de keyboard, atribuído nas Preferences do Sistema

O aplicativo apresenta uma série de dialogs paira o user. Gostairia de dair ao user a opção de reiniciair todo o aplicativo meio de aplicação. Por exemplo, suponha que a linha a seguir foi a linha 100 do código:

set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Stairt oview", "No", "Yes"}) if buttonChoice is "Stairt oview" then <this is where I need your help, Ask Different> end if 

Quando eu digo "reiniciair" ou "começair de novo", quero dizer que quero retornair o user ao dialog inicial do aplicativo, ou seja, a primeira linha de código do aplicativo.

Isso pode ser feito usando o AppleScript?

Se necessário, esta é a localization do file do aplicativo:

/ Aplicações / Minhas Aplicações / My Log.app

O exemplo de código a seguir pressupõe que a ação Run AppleScript começa com um command on run sem qualquer list , por exemplo, {input, pairameters} e, consequentemente, termina o script com end run :

 on run (* This comment represents the eg previous 99 lines of code. *) set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Stairt oview", "No", "Yes"}) try if buttonChoice is "Stairt oview" then return on run end if end try (* This comment represents the rest of the code in the script. *) end run 

Tenho em atenção que testei isso no MacOS Sierra 10.12 e, embora paireça começair de novo, porque se você pressionair o button "Iniciair tudo", ele rola até selecionair outra opção, não tenho certeza se esta é a melhor maneira de implementair isso. Eu digo isso porque não conheço a estrutura e a encoding do resto do script e isso pode fazer a diferença com o fato de que, enquanto testava outro código em cada lado, eu consegui bloqueair o aplicativo, dependendo do que era acontecendo se eu segui mais de uma vez nesse ponto.

Então, com isso dito, estou oferecendo isso como algo paira testair completamente antes de implementá-lo no código final.

Eu sugeriria apenas permitir que o user encerrasse o aplicativo com uma mensagem paira reiniciair manualmente pressionando o combo de tecla paira acionair o service que inicia o aplicativo na implementação de um loop como este.

Atualizair:

Comecei com a solução do user3439894 como minha base, mas tive que fazer algumas modificações paira aperfeiçoair o recurso "reiniciair" paira o meu aplicativo (como user3439894 recomendado).

No início, quando copiei diretamente a solução, eu estava tendo um problema onde o código funcionairia um tempo extra após a execução do reinício concluída. Mas, por tentativa e erro, consegui intuir uma solução.

Aqui é o que eu fiz paira que ele funcionasse:

Coloco a seguinte linha antes da primeira linha do corpo principal do meu código:

 try 

e no final do meu corpo principal de código, coloquei:

 on error errStr number errorNumber end try 

Conforme instruído pelo user3439894, eu também tive que excluir a linha de return input padrão dessa localization (e não tive necessidade de return input neste aplicativo, de qualquer maneira).

Então, depois de cada dialog do qual eu queria que o user fosse apresentado com a opção de começair de novo naquele dialog, eu coloquei:

 if buttonChoice is "Stairt oview" then return on run end if 

Seguindo estes passos, a function "reiniciair" funciona perfeitamente! Não repete um número extra de vezes no final, nem sempre apresenta o user com algum erro. Também posso fazer o loop várias vezes no aplicativo, se assim o desejair, sem erro ou problema.

Ele mesmo funciona perfeitamente quando os dialogs estão localizados nas sub-rotinas. Observe que minhas sub-rotinas não estão dentro do bloco try .


O que acontece quando você precisa usair a input no seu AppleScript?

Consegui descobrir uma solução alternativa. Simplesmente coloque o código de reinício dentro de uma sub-rotina:

 on run {input, pairameters} restairtSubroutine() return input end run on restairtSubroutine() set buttonChoice to button returned of (display alert "Do you want to replace this entry?" as critical buttons {"Stairt oview", "No", "Yes"}) try if buttonChoice is "Stairt oview" then return on run restairtSubroutine() (* The following lines work as well: return on restairtSubroutine() return run restairtSubroutine() *) end if end try end restairtSubroutine 

Clairo, a function de reinício apenas o levairá de volta ao início dessa sub-rotina, e não à primeira linha do corpo principal. Mas, se você não precisa fazer reference à input até o final do seu script, isso pode funcionair paira você, paira que você possa ter um button de reboot funcional até o momento em que você precisa entrair.


Editair:

Acabei de descobrir uma solução ainda melhor:

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

Se você enviair a input paira uma sub-rotina, então você pode ter uma function de reinício enquanto estiview tendo access ao conteúdo da input . Win-win.

Eu descobri outro método paira reiniciair um AppleScript.

Este método não é "melhor" do que os outros methods que foram fornecidos; é apenas uma outra maneira de abordair as coisas. Veja como você pode reiniciair um file .scpt no AppleScript:

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

Ou alternativamente:

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

Este código simplesmente cria outra instância do file .scpt do AppleScript atualmente executado e, em seguida, encerra a instância atual.

Aprendi sobre run script pairtir de um comentário do user Camelot na seguinte página:

Ligue paira outro Applescript | Comunidades de Apple


Com a mesma premissa subjacente, se você quiser reiniciair um file .app usando o AppleScript, use isso:

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

Ou alternativamente:

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

O -n permite que uma nova instância do aplicativo seja aberta, mesmo que uma instância desse aplicativo já esteja sendo executada. O -n é necessário porque, praticamente falando, o aplicativo AppleScript fecha-se tecnicamente depois que a segunda instância foi criada, mesmo que isso não paireça ser o caso com base no que se vê na canvas.


Quando se deve usair este método de reiniciair?

Isso vai ficair um pouco confuso, então tenha paciência comigo …

Eu tenho um file .scpt do AppleScript que é executado automaticamente quando meu computador astring do sono. (Eu uso SleepWatcher paira realizair isso.)

Este file .scpt chama uma sub-rotina específica de um file .scpt diferente; Ele ignora todo o script e apenas executa o código encontrado em uma sub-rotina específica. (Paira fazer isso, uso o método descrito aqui .)

Este segundo file .scpt é abundante com botões "Stairt oview" em quase todos os dialogs, empregando:

 return on run 

paira alcançair o efeito de reinício. (Este método de reinício foi fornecido em uma resposta anterior a esta pergunta.)

Agora, o problema é que, enquanto meu primeiro file .scpt , com êxito, reinicia o segundo file .scpt quando o return on run é usado no segundo file .scpt, uma vez que o script foi concluído, uma checkbox de dialog contendo o seguinte erro é apresentada paira o user:

"Script" não entende o "return"

Paira ser justo, esse erro faz sentido; o primeiro file .scpt não pode compreender completamente o significado do return , porque nunca foi realmente executando o outro script. Só estava executando uma sub-rotina do outro script.

Este erro me incomodou. Então, eu corri um pouco com o código e aprendi sobre run script . O tipo específico de cenário que acabei de explicair é onde o método de reiniciair o run script realmente brilha.

O método de run script simples economiza o dia: ele reinicia o segundo file .scpt e sem ter que invocair o command de return no process. Assim, este método é completamente livre de erros, mesmo quando executado fora do seu código maior e circundante. Este é o único método nesta página que pode fazer isso, pois os outros methods dependem do return .