Як я можу перезапустити щойно запущений додаток із AppleScript?


3

Я створив додаток з дією "Запустити AppleScript" в Automator.

Я створив службу в Automator, яка запускає вищезгаданий додаток.

Служба запускається ярликом клавіатури, призначеним у налаштуваннях системи

Додаток представляє користувачеві ряд діалогів. Я хотів би дати користувачеві можливість перезапустити всю програму в середині програми. Наприклад, припустимо, що наступний рядок був рядком 100 коду:

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

Коли я кажу «перезапустити» або «почати спочатку», я маю на увазі, що хочу повернути користувача до початкового діалогового вікна програми, тобто самого першого рядка коду програми.

Це можна зробити за допомогою AppleScript?

Якщо потрібно, це розташування файлу програми:

/ Програми / Мої програми / Мій журнал.app


1
Чи є спосіб, який ви можете пояснити більш детально? Тому що я опублікував відповідь, і мені було зазначено в коментарі, що моя відповідь не дуже вирішує ваше питання.
wch1zpink

«Ви хочете замінити цей запис?» попередження вище - це, наприклад, десятий діалог, представлений користувачеві. Я хотів би, щоб програма повністю перезапустилася, починаючи з першого рядка коду, якщо buttonChoice є "Почати спочатку " , як підозрюється @ user3439894. Прошу вибачення, якщо це було не ясно.
сфера

Отже, ваш "Мій Log.app" в основному містить купу різних послідовних діалогів? Я думаю, що це ви говорите, тому я відредагую свою оригінальну відповідь. Дякую
wch1zpink

Він виконує інші функції, такі як написання тексту у файл та читання тексту з файлу, але, так, "Мій журнал.app" - це, як правило, купа різних послідовних діалогів.
сфера

Відповіді:


2

У наведеному нижче прикладі коду припускається, що дія Запустити AppleScript починається з команди без будь-якого списку , наприклад, і, отже, закінчується сценарій :on run {input, parameters}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

Зауважте, що я перевірив це в macOS Sierra 10.12, і, мабуть, він починається заново, тому що якщо натиснути кнопку "Почати з початку", вона циклічне, поки ви не обрали інший вибір, я не впевнений, що це найкращий спосіб здійснити це. Я кажу, що тому, що я не знаю структуру та кодування решти сценарію, і це може змінити значення разом з тим, що під час тестування іншого коду з кожного боку цього, я зміг зірвати додаток залежно від того, що було триває, якщо я в цій точці зациклився більше, ніж один раз.

Тож із цим сказаним я пропоную це як щось перевірити, перш ніж реалізувати його у кінцевому коді.

Я б запропонував просто дозволити користувачу закрити додаток із повідомленням про перезапуск вручну, натиснувши клавішу-комбо, щоб запустити службу, яка запускає додаток, через впровадження циклу, такого як цей.


1

Оновлення:

Я почав з базового рішення user3439894, але мені довелося внести кілька модифікацій, щоб удосконалити функцію "перезавантаження" для мого додатка (як рекомендував user3439894).

Спочатку, коли я безпосередньо скопіював рішення, у мене виникла проблема, коли код запустився ще один додатковий час після завершення повторного запуску. Але, шляхом спроб та помилок, мені вдалося зрозуміти рішення.

Ось що я зробив, щоб змусити його працювати:

Я ставлю наступний рядок перед самим першим рядком основного тексту свого коду:

try

і в кінці свого основного коду я кладу:

on error errStr number errorNumber
end try

Згідно з вказівкою користувача3439894, мені також довелося видалити return inputрядок за замовчуванням з цього місця (і я не мав потреби return inputв цьому додатку).

Потім, після кожного діалогового діалогового вікна, з якого я хотів, щоб користувачеві було запропоновано можливість починати в цьому діалоговому вікні, я ставлю:

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

Виконуючи ці кроки, функція «перезавантаження» прекрасно працює! Він не повторюється зайву кількість разів в кінці, і ніколи не показує користувачеві якоїсь помилки. Я також можу робити циклічну програму кілька разів, якщо цього хочу, без помилок чи проблем.

Він навіть ідеально працює, коли діалоги розташовані в підпрограмах. Зауважте, що мої підпрограми не знаходяться в tryблоці.


Що відбувається, коли вам потрібно використовувати inputу своєму AppleScript?

Мені вдалося виявити вирішення проблеми. Просто помістіть код перезапуску в підпрограму:

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

Звичайно, функція перезавантаження поверне вас лише до початку цієї підпрограми, а не до першого рядка основного тіла. Але якщо вам не потрібно посилатися на inputкінець сценарію, це може працювати для вас, щоб ви могли мати функціональну кнопку перезапуску аж до того моменту, який вам потрібен input.


Редагувати:

Я щойно придумав ще кращий спосіб вирішення:

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

Якщо ви надсилаєте inputпідпрограму, тоді ви можете мати функцію перезавантаження, отримуючи доступ до inputвмісту. Безпрограшний.


@ user3439894 Чи добре це рішення чи ви бачите в ньому потенційні проблеми?
сфера

Якщо він працює для вас у міру необхідності / бажаності і не викликає помилок, я не бачу жодних проблем з його використанням.
користувач3439894

0

Я відкрив ще один метод перезапуску AppleScript.

Цей метод не «кращий», ніж інші методи, які були надані; це просто ще один спосіб наближення речей. Ось як можна перезапустити .scpt файл у AppleScript:

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

Або, як варіант:

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

Цей код просто створює інший екземпляр поточного запущеного файлу AppleScript .scpt, а потім закриває поточний екземпляр.

Я дізнався про run scriptкоментар користувача Camelot на наступній веб-сторінці:

Зателефонуйте до іншого яблучного | Apple Communities


З тією ж базовою умовою, якщо ви хочете перезапустити .app-файл за допомогою AppleScript, використовуйте це:

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

Або, як варіант:

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

-nДозволяє новий екземпляр додатку , щоб відкрити, навіть якщо екземпляр цього додатка вже запущений. Це -nнеобхідно, тому що, практично кажучи, додаток AppleScript технічно закривається після створення другої інстанції, навіть якщо це може виявитися не на основі того, що ви бачите на своєму екрані.


Коли слід використовувати цей метод перезавантаження?

Це стане трохи заплутаним, тож потерпіть зі мною ...

У мене є файл AppleScript .scpt, який автоматично запускається, коли мій комп'ютер прокидається зі сну. (Для цього я використовую SleepWatcher .)

Цей файл .scpt викликає конкретну підпрограму іншого файлу .scpt; він пропускає весь сценарій і виконує лише той код, який знаходиться в одній конкретній підпрограмі. (Для цього я використовую описаний тут метод .)

У цьому другому .scpt-файлі майже в кожному діалоговому вікні є кнопки "Почати спочатку", використовуючи:

return on run

для досягнення ефекту перезавантаження. (Цей метод перезапуску був наданий у попередній відповіді на це питання.)

Тепер проблема полягає в тому, що мій перший .scpt файл насправді успішно перезапускає другий .scpt-файл, коли return on runвін використовується у другому .scpt-файлі, після завершення сценарію користувачеві відкривається діалогове вікно, що містить наступну помилку. :

«Сценарій» не розуміє «повернення»

Якщо чесно, ця помилка має сенс; перший .scpt файл не може повністю зрозуміти значущість return, оскільки він ніколи по-справжньому не запускав інший сценарій. Він виконував лише одну підпрограму іншого сценарію.

Ця помилка помилила мене. Отже, я ще більше розібрався з кодом і дізнався про це run script. Конкретний тип сценарію, який я щойно пояснив, полягає в тому, де run scriptсправді світить метод перезапуску.

Простий run scriptметод економить день: він перезавантажує другий .scpt файл і без необхідності викликати returnкоманду в процесі. Таким чином, цей метод є абсолютно безпомилковим, навіть коли він використовується поза його більшим, оточуючим кодом. Це єдиний метод на цій сторінці, який може це зробити, оскільки інші методи покладаються на return.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.