Как постоянно запускать собственный AppleScript в фоновом режиме?

Учитывая файл AppleScript, предназначенный для опроса диалогового окна приложения каждые 30 секунд, как я могу легко настроить свою Mac OS так, чтобы этот файл AppleScript запускался каждый раз, когда я тихо вхожу в фоновый режим?

Код для скрипта (в случае заинтересованности) указан ниже и предназначен для нажатия «Позже» в бета-приложении AirMail:

repeat
    if (exists application "AirMail Beta") then
        tell application "System Events" to tell process "Airmail Beta"
            if exists (button "Later" of front window) then
                click (button "Later" of front window)
            end if
        end tell
    end if
    delay 30
end repeat

Приведенный выше скрипт работает, но если кто-то может придумать лучший способ автоматически щелкнуть диалоговое окно без написания AppleScript, который опрашивает каждые несколько секунд, не стесняйтесь предлагать такое решение в комментариях. В основном, я хотел бы знать, как лучше всего управлять сценариями AppleScript, предназначенными для непрерывной работы, чтобы их можно было включать / отключать и запускать, не увидев при входе в систему автоматически.

Ответы (4)

На мой взгляд, лучший способ сделать это — использовать собственный планировщик задач Apple: launchd, потому что вам не нужно устанавливать стороннее программное обеспечение. Во-первых, теория: чтобы запустить скрипт из командной строки, вы просто запускаете:

osascript /PATH/TO/YOUR/script.scpt

Зная это, все, что вам нужно сделать, это создать plistфайл ~/Library/LaunchAgents/с этим:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Label</key>
    <string>air-mail-beta.job</string>
    <key>ProgramArguments</key>
    <array>
        <string>/usr/bin/osascript</string>
        <string>/PATH/TO/YOUR/SCRIPT</string>
    </array>
    <key>RunAtLoad</key>
    <true/>
</dict>
</plist>

Имя файла plistне имеет значения, но оно должно быть в формате ~/Library/LaunchAgents/. Кроме того, не забудьте изменить /PATH/TO/YOUR/SCRIPTсоответствующим образом.

Наконец, вам просто нужно сказать launchd, что вы хотите, чтобы этот скрипт всегда запускался. Для этого вы просто делаете:

launchctl load -w ~/Library/LaunchAgents/NAME-OF-YOUR-PLIST.plist

и вы сделали! Если похоже, что скрипт не запустился, вы можете сделать это:

 launchctl start air-mail-beta.job

где air-mail-beta.jobсвойство <key>label</key>, которое мы установили в plistфайле.

Наконец, если вам когда-нибудь понадобится отключить скрипт, не забудьте сделать unloadэто с помощью:

launchctl unload -w ~/Library/LaunchAgents/NAME-OF-YOUR-PLIST.plist

Я знаю, что это решение более техническое, но поверьте мне, это лучший способ решить вашу проблему. Если у вас есть какие-либо вопросы, просто спросите!

Спасибо за это решение. Может ли имя .jobбыть любым в .plistфайле? Я попытался создать обычай .plist, и он, кажется, успешно загружает .plistwith launchhd, но сам скрипт, похоже, не запускается. После этого я не получаю обратной связи в терминале launchctl. Я знаю, что сценарий работает, потому что если я просто сделаю osascript /PATH/to/script.scptто, что должен.
Испытывает ту же проблему, что и @Winterflags

Первый шаг:

При сохранении сценария в редакторе сценариев сохраните его как пакет приложений, а затем добавьте его в элементы автозагрузки в системных настройках входа.

Шаг второй «Фон»

Используйте приложение iBackground Scripts для Mac

Просто перетащите AppleScript, который был сохранен как «Набор приложений», в эту каплю. При нажатии на кнопку «Да» ваш скрипт будет работать в фоновом режиме и не будет отображаться в доке.

Я не уверен, как работает iBackground, но в зависимости от того, какую настройку он меняет в сохраненном файле info.plist сценария, приложение может работать в полном фоновом режиме, что означает, что вы не можете легко выйти из него, потому что теперь оно действует как процесс и не отображает графический интерфейс.
Вы можете отменить его, нажав кнопку «Нет», и он больше не будет фоновым сценарием и будет отображаться в доке. Если вы не видите изменения сразу, переместите AppleScript в другое место (Command + перетаскивание).
Вы подтверждаете, что хотите выйти из него, вы не можете сделать это через графический интерфейс, если вы используете это приложение, чтобы внести изменения в фоновое приложение.

У меня была такая же проблема. Я пытался нажать кнопку «ОК» в контакте в фоновом режиме, когда я использовал свой компьютер. В итоге это сработало для меня.

tell application "System Events"
    if exists of application process "Kontakt 5" then
        tell application "Kontakt 5.6.0" to activate
        delay 0.5
        repeat
            try
                click UI element "OK" of window 1 of application process "Kontakt 5"
            end try
        end repeat
    end if
end tell

Вы можете добавить процедуру остановки в свой фоновый скрипт. Затем вы пишете другой сценарий для вызова стопора вашей фоновой процедуры... Требуется некоторая сборка.

как вызвать stringSet в операторе другого скрипта:

on run
    set myApp to "/Applications/applescriptFiles/demo -- the best/b.app"
    -- some hocus pocus is nesessary to avoid applescript from change path.
    -- set myApp to POSIX file myApp

    tell application myApp

        launch
        stringSet("stringie set") -- this function is in the "b" app.
    end tell
end run


(* 

save this as an application bundle 

invoked by a.app.  

twtwtw write in:
https://discussions.apple.com/thread/4917321?start=15&tstart=0

hocus-pocus: 

Give your script application a unique bundle id string (CFBundleIdentifier) and a unique bundle name (CFBundleName) too, to make life easier.  You set those in the info.plist file.  Launch the script app once to register it with launch services, and system will be able to find it thereafter.

Example:
      <key>CFBundleIdentifier</key>
      <string>com.rccharles.b</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>b</string>

    I added the CFBundleIdentifier info above the CFBundleInfoDictionaryVersion line. I left the CFBundleInfoDictionaryVersion and CFBundleName as is.

    *)

property myVar : "initial value"

on run
    display dialog myVar
end run

on stringSet(inputVar)
    set myVar to inputVar
    display dialog "variable myVar is " & myVar
end stringSet