Jak mogę ponownie uruchomić aktualnie uruchomioną aplikację za pomocą AppleScript?


4

Stworzyłem aplikację z działaniem „Uruchom AppleScript” w Automatorze.

Stworzyłem usługę w Automatorze, która uruchamia wspomnianą aplikację.

Usługa jest uruchamiana przez skrót klawiaturowy, przypisany w Preferencjach systemowych

Aplikacja przedstawia użytkownikowi szereg okien dialogowych. Chciałbym dać użytkownikowi opcję ponownego uruchomienia całej aplikacji w trakcie aplikacji. Załóżmy na przykład, że następującą linią był wiersz 100 kodu:

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

Kiedy mówię „uruchom ponownie” lub „zacznij od nowa”, mam na myśli to, że chcę przywrócić użytkownikowi początkowe okno aplikacji, to znaczy pierwszą linię kodu aplikacji.

Czy można to zrobić za pomocą AppleScript?

W razie potrzeby jest to lokalizacja pliku aplikacji:

/ Aplikacje / Moje aplikacje / My Log.app


1
Czy jest jakiś sposób, który możesz wyjaśnić bardziej szczegółowo? Ponieważ wysłałem odpowiedź i zwrócono mi uwagę w komentarzu, że moja odpowiedź tak naprawdę nie rozwiązuje twojego problemu.
wch1zpink

The „Czy chcesz zastąpić ten wpis?” powyższy alert to na przykład dziesiąte okno dialogowe przedstawione użytkownikowi. Chciałbym, aby aplikacja całkowicie się zrestartowała, od pierwszej linii kodu, jeśli buttonChoice jest "Zacząć od nowa" , jak podejrzewał @ user3439894. Przepraszam, jeśli nie było to jasne.
rubik's sphere

Więc twój „My Log.app” zasadniczo zawiera kilka różnych kolejnych okien dialogowych? Myślę, że to właśnie mówisz, więc zmienię moją oryginalną odpowiedź. Dziękuję Ci
wch1zpink

Wypełnia inne funkcje, takie jak pisanie tekstu do pliku i czytanie tekstu z pliku, ale tak, „My Log.app” to w zasadzie tylko kilka różnych kolejnych okien dialogowych.
rubik's sphere

Odpowiedzi:


2

Następujące kod przykład załóżmy, że Uruchom AppleScript akcja zaczyna się od on run dowództwo bez lista , np. {input, parameters} iw konsekwencji kończy skrypt za pomocą 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

Zwróć uwagę, że przetestowałem to w macOS Sierra 10.12 i chociaż wydaje się, że zaczyna się od nowa, ponieważ jeśli naciśniesz przycisk „Zacznij od nowa”, zapętli się, aż wybierzesz inny wybór, nie jestem pewien, czy jest to najlepszy sposób na wdrożenie tego. Mówię to, ponieważ nie znam struktury i kodowania reszty skryptu i tego może zrobić różnicę wraz z faktem, że podczas testowania innych kod po każdej stronie mogłem rozbić aplikację w zależności od tego, co się działo, jeśli w tym momencie zapętliłem więcej niż raz.

Powiedziawszy to, oferuję to jako coś do przetestowania przed wprowadzeniem go do ostatecznego kodu.

Proponuję po prostu zezwolenie użytkownikowi na zamknięcie aplikacji za pomocą wiadomości do ręcznego ponownego uruchomienia przez naciśnięcie klawisza-kombinacji, aby uruchomić usługę, która uruchamia aplikację nad implementacją pętli takiej jak ta.


1

Aktualizacja:

Zacząłem od rozwiązania user3439894 jako mojej bazy, ale musiałem dokonać kilku modyfikacji, aby udoskonalić funkcję „restart” dla mojej aplikacji (zgodnie z zaleceniem użytkownika 3439894).

Na początku, gdy bezpośrednio skopiowałem rozwiązanie, miałem problem z tym, że kod uruchomiłby się jeszcze jeden raz po zakończeniu restartowanego uruchomienia. Ale metodą prób i błędów udało mi się wyczuć rozwiązanie.

Oto co zrobiłem, żeby to zadziałało:

Przed pierwszą linią głównej części mojego kodu umieściłem następujący wiersz:

try

a na końcu mojej głównej części kodu umieściłem:

on error errStr number errorNumber
end try

Zgodnie z instrukcjami użytkownika 3439894 musiałem również usunąć domyślne return input linia z tej lokalizacji (i nie musiałem tego robić) return input w tej aplikacji).

Następnie, po każdym oknie dialogowym, które chciałem przedstawić użytkownikowi z opcją rozpoczęcia w tym oknie dialogowym, umieściłem:

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

Po wykonaniu tych czynności funkcja „restart” działa doskonale! Nie powtórzy to więcej razy na końcu, ani nigdy nie przedstawia użytkownikowi błędu. Mogę również wielokrotnie uruchamiać aplikację, jeśli tego chcę, bez błędu lub problemu.

Działa nawet doskonale, gdy okna dialogowe znajdują się w podprogramach. Zauważ, że moje podprogramy są nie w obrębie try blok.


Co się dzieje, gdy musisz użyć input w swoim AppleScript?

Udało mi się znaleźć obejście. Po prostu umieść kod restartu w podprogramie:

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

Oczywiście funkcja restartu przeniesie Cię z powrotem tylko na początek tego podprogramu, a nie do pierwszej linii głównej. Ale jeśli nie musisz odwoływać się do input do końca twojego skryptu może to zadziałać tak, że możesz mieć funkcjonalny przycisk restartu aż do momentu, którego potrzebujesz input.


Edytować:

Właśnie wymyśliłem jeszcze lepsze obejście:

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

Jeśli wyślesz input do podprogramu, wtedy możesz mieć funkcję restartu, mając dostęp do input zawartość. Win-win.


@ user3439894 Czy to rozwiązanie jest w porządku, czy widzisz z nim potencjalne problemy?
rubik's sphere

Jeśli to działa dla Ciebie w sposób potrzebny / pożądany i nie powoduje błędów, nie widzę żadnego problemu z używaniem go.
user3439894

0

Odkryłem inną metodę ponownego uruchomienia AppleScript.

Ta metoda nie jest „lepsza” niż inne dostarczone metody; to tylko kolejny sposób zbliżania się do rzeczy. Oto jak możesz ponownie uruchomić plik .scpt w AppleScript:

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

Lub alternatywnie:

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

Ten kod po prostu tworzy inną instancję aktualnie uruchomionego pliku AppleScript .scpt, a następnie zamyka bieżącą instancję.

nauczyłem się o run script z komentarza użytkownika Camelot na następującej stronie internetowej:

Zadzwoń do kolejnego Jabłka | Społeczności Apple


Z tą samą podstawową przesłanką, jeśli chcesz ponownie uruchomić plik .app za pomocą AppleScript, użyj tego:

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

Lub alternatywnie:

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

The -n umożliwia otwarcie nowej instancji aplikacji, nawet jeśli instancja tej aplikacji jest już uruchomiona. The -n jest konieczne, ponieważ praktycznie rzecz biorąc, aplikacja AppleScript jest technicznie zamknięta po utworzeniu drugiej instancji, chociaż może się tak nie wydawać na podstawie tego, co widzi się na ekranie.


Kiedy należy użyć tej metody ponownego uruchomienia?

To będzie trochę mylące, więc miejcie ze mną ...

Mam plik AppleScript .scpt, który uruchamia się automatycznie, gdy komputer budzi się ze snu. (Używam SleepWatcher do osiągnięcia tego.)

Ten plik .scpt wywołuje określony podprogram innego pliku .scpt; pomija cały skrypt i uruchamia tylko kod znaleziony w jednym, określonym podprogramie. (Aby to osiągnąć, używam metody opisany tutaj .)

Ten drugi plik .scpt jest bogaty w przyciski „Rozpocznij od” w prawie każdym oknie, wykorzystując:

return on run

aby osiągnąć efekt ponownego uruchomienia. (Ta metoda ponownego uruchomienia została podana w poprzedniej odpowiedzi na to pytanie).

Problem polega na tym, że mój pierwszy plik .scpt w rzeczywistości pomyślnie się restartuje drugi plik .scpt, gdy return on run jest używany w drugim pliku .scpt, gdy skrypt zostanie zakończony, użytkownikowi zostanie wyświetlone okno dialogowe zawierające następujący błąd:

«Skrypt» nie rozumie „powrotu”

Aby być uczciwym, ten błąd ma sens; pierwszy plik .scpt nie może w pełni zrozumieć znaczenia return, ponieważ nigdy tak naprawdę nie uruchamiał drugiego skryptu. Działa tylko jeden podprogram innego skryptu.

Ten błąd mnie podsłuchał. Więc trochę więcej pomieszałem z kodem i dowiedziałem się o nim run script. Konkretny typ scenariusza, który właśnie wyjaśniłem, to gdzie run script metoda restartu naprawdę świeci.

Prosty run script metoda zapisuje dzień: ponownie uruchamia drugi plik .scpt i bez konieczności wywoływania return polecenie w procesie. Zatem ta metoda jest całkowicie wolna od błędów, nawet gdy jest uruchamiana poza swoim większym, otaczającym kodem. Jest to jedyna metoda na tej stronie, która może to zrobić, ponieważ inne metody są od niej zależne return.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.