Вопрос или проблема
Я использую следующий скрипт
<?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>my.script.keeprunning</string>
<key>KeepAlive</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/path/to/file</string>
</array>
</dict>
</plist>
чтобы запустить приложение, даже когда оно ломается, но после перезагрузки системы фокус переключается на это конкретное приложение. Как я могу улучшить скрипт, чтобы запустить приложение скрыто или сведенным? Будет ли легче написать AppleScript для этого и запустить его как службу?
Спасибо за ваши предложения 😉
У меня есть скрипт, который решает аналогичную задачу, и вот модифицированная версия, которая была протестирована на нескольких различных приложениях.
on idle
tell application "System Events"
set pName to the name of every process
if pName does not contain "MY APPLICATION" then
do shell script "open -g /Applications/MY APPLICATION.app"
-- или где бы ни находилось ваше приложение
else if pName contains "MY APPLICATION" then
set makeFalse to visible of window 1 of application "MY APPLICATION"
if makeFalse is true then set visible of window 1 of application "MY APPLICATION" to false
end if
end tell
end idle
Обратите внимание, что этот скрипт должен быть сохранен как приложение “остаться открытым” и может быть добавлен в ваш список элементов запуска, чтобы загружаться автоматически при перезагрузке системы.
Как только он запущен, скрипт будет выполнять следующее:
- Проверять запущенные процессы, чтобы узнать, открыто ли ваше приложение.
- Если вашего приложения нет в списке, оно откроется в фоновом режиме с помощью команды
do shell script "open -g
. - Если приложение открыто, оно скроет главное окно.
- Обработчик
on idle
будет автоматически проверять каждые 30 секунд. Если вы хотите увеличить задержку, вы можете добавитьreturn
, а затем количество секунд, которые вы бы хотели, чтобы скрипт ждал перед следующей проверкой (например,return 300
для пяти минут). Это следует добавить передend idle
Я использую эту информацию для скрытия иконки дока для приложения и его полного выполнения в фоновом режиме.
Например, сохраните этот plist как ~/Library/LaunchAgents/some.label.plist
:
<?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>some.label</string>
<key>ProgramArguments</key>
<array>
<string>lsappinfo</string>
<string>launch</string>
<string>launchandhide=true</string>
<string>nofront=true</string>
<string>/Applications/Mail.app</string>
</array>
<key>StartInterval</key>
<integer>60</integer> <!-- запустить программу каждые 60 секунд -->
</dict>
</plist>
Затем запустите launchctl load ~/Library/LaunchAgents/some.label.plist
.
Вы также можете использовать open -jga Mail
или pgrep -qx Mail||open -jga Mail
вместо lsappinfo launch launchandhide=true nofront=true /Applications/Mail.app
. open -jg
открывает приложение скрыто и без выставления его на передний план, за исключением того, что для некоторых приложений, таких как Mail и TextEdit, оно создает новое видимое окно, если приложение запущено, но не имеет открытых окон. Для этих приложений вы можете использовать pgrep
для проверки, открыто ли приложение уже.
lsappinfo
был добавлен в 10.9. open -j
и pgrep
были добавлены в 10.8.
Ответ или решение
Создание LaunchAgent для скрытого запуска приложения на macOS
Настраивая LaunchAgent для автоматического и скрытого запуска приложения на macOS, вы можете обеспечить его постоянную работу, даже при сбоях. Ваша текущая реализация использует plist, однако чтобы избежать переключения фокуса на приложение при перезагрузке, вы можете доработать ваш скрипт. Мы рассмотрим, как это сделать с использованием как plist, так и AppleScript.
Настройка LaunchAgent
Ваш текущий plist выглядит следующим образом:
<?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>my.script.keeprunning</string>
<key>KeepAlive</key>
<true/>
<key>ProgramArguments</key>
<array>
<string>/path/to/file</string>
</array>
</dict>
</plist>
Чтобы сделать приложение скрытым, вы можете использовать команду open -g
в AppleScript, которая открывает приложение в фоновом режиме. В условии, когда приложение перестает быть открытым, можно управлять его запуском через do shell script
.
Пример AppleScript для скрытого запуска
Вот модифицированный скрипт, который будет проверять, запущено ли ваше приложение, а если нет, – запускать его скрыто:
on idle
tell application "System Events"
set pName to the name of every process
if pName does not contain "MY APPLICATION" then
do shell script "open -g /Applications/MY APPLICATION.app"
else if pName contains "MY APPLICATION" then
tell application "MY APPLICATION"
set visible of window 1 to false
end tell
end if
end tell
return 30 -- интервал проверки в 30 секунд
end idle
Как использовать AppleScript
- Сохраните этот скрипт в качестве «остановленного приложения» (stay-open application).
- Добавьте его в элементы входа в систему, чтобы он загружался автоматически при старте системы.
Простой вариант с использованием плага
Если вы хотите избежать создания дополнительного AppleScript, можете добавить следующую конфигурацию в ваш plist:
<key>ProgramArguments</key>
<array>
<string>/usr/bin/open</string>
<string>-g</string>
<string>/Applications/MY APPLICATION.app</string>
</array>
Замените путь на путь к вашему приложению.
Примечания по работе с plist
- Сохраните ваш изменённый plist файл в директории
~/Library/LaunchAgents/
с уникальным названием, например,com.myscript.keeprunning.plist
. -
Загрузите plist с помощью команды:
launchctl load ~/Library/LaunchAgents/com.myscript.keeprunning.plist
Заключение
Создание LaunchAgent и интеграция его с AppleScript – это надежный способ поддерживать ваше приложение запущенным, даже в случае сбоев, при этом оно остается скрытым от пользователей. Такой подход не только предотвращает отвлечение внимания на приложение, но и позволяет вам контролировать его состояния через регулярные проверки.
Если у вас есть вопросы или требуется дальнейшая помощь, не стесняйтесь обращаться.