У меня есть служба приложений, которую я хочу запустить при запуске системы с файлом plist:
<!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>com.my.app.ident</string>
<key>ProgramArguments</key>
<array>
<string>/Users/me/Desktop/MyApp/App</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>StandardOutPath</key>
<string>/Users/me/Desktop/MyApp/logfile.log</string>
<key>StandardErrorPath</key>
<string>/Users/me/Desktop/MyApp/logerr.log</string>
<key>UserName</key>
<string>me</string>
</dict>
</plist>
Это было создано с
sudo chown root:wheel /Library/LaunchDaemons/com.my.app.ident.plist
и разрешения
sudo chmod a+x /Library/LaunchDaemons/com.my.app.ident.plist
а затем загружается:
sudo launchctl load -w /Library/LaunchDaemons/com.my.app.ident.plist
Приложение имеет такие разрешения, как:
-rwxr-xr-x 1 me staff 54755728 29 Nov 12:46 App
Который работает нормально, но не запускается с системой - он просто записывает ошибки в logerr.log, повторяя:
Couldn't memory map the bundle file for reading.
A fatal error occured while processing application bundle
Failed to map file. open(/Users/me/Desktop/MyApp/App) failed with error 1
Failure processing application bundle.
Эти ошибки прекращаются, когда пользователь «я» входит в систему, а затем служба начинает работать. Мне нужно, чтобы это работало без входа «я».
есть идеи?
Это основное консольное приложение dotnet. У него нет собственного пользовательского интерфейса, только веб-сервер. 2 нет 3 нет 4 нет еще нет Вы думаете, что это будет иметь значение?
Хорошо, для веб-сервиса LaunchDaemon имеет смысл. Я думаю, что (4) стоит попробовать. Чтобы уточнить, это в комплекте .app? Потому что ошибки предполагают, что это так, но путь предполагает, что это не так. Если это пакет .app, проблема также возникает с переносом приложений. Я не очень хорошо знаком с тем, как dotnet работает с macOS — является ли ваша программа настоящим исполняемым двоичным файлом macOS (Mach-O) или она запускает среду выполнения, которая загружает сборку dotnet, содержащую код? Если это что-то иное, чем собственный двоичный файл, возможно, он не сможет найти другие файлы, необходимые для запуска.
Это собственный двоичный файл
@pmdj, поэтому кажется, что его установка в /Applications/ решает проблему. По какой-то причине наличие его в каталоге Users означает, что он не может его запустить, что странно, поскольку я думал, что LaunchDaemon работает от имени пользователя root? Но ничего, большое спасибо за идею!
В вашем случае из-за <key>UserName</key> <string>me</string>
он не запускается от имени пользователя root, хотя, если имя соответствует Users/me
, можно подумать, что это не проблема. Я не совсем уверен, какой механизм предотвращает доступ здесь, но предварительный вход в систему — это странно заблокированная среда, поэтому я не особенно удивлен.
Я подозреваю, что это связано с системой согласия «Файлы и папки», которая защищает различные подпапки домашнего каталога, такие как «Рабочий стол», «Документы», «Загрузки» и т. д. (см. Панель настроек системы «Безопасность и конфиденциальность»)
Из обсуждения в комментариях мы сузили его до проблемы пути. Точный механизм, предотвращающий доступ, здесь мне не ясен на 100%, но предварительный вход — это довольно заблокированная среда, поэтому я не очень удивлен, что он не работает из папки рабочего стола вашего пользователя.
Я подозреваю, что в вашем конкретном случае это сводится к системе согласия: вошедший в систему пользователь должен предоставить каждому процессу доступ к определенным каталогам, таким как Desktop
, Documents
, Downloads
и т. д., и поскольку пользователь не вошел в систему, будет не будет письменного согласия.
Если ваш исполняемый файл находится внутри пакета .app, перенос приложения будет дополнительной проблемой.
Решение состоит в том, чтобы установить демон запуска или глобальные двоичные файлы агента запуска для всей системы. Если они являются частью пакета .app, установите приложение в /Applications
(это также позволит избежать проблем с перемещением приложения). В противном случае «хорошее» расположение /Library/Application Support/[Your-Application]/
.
Кстати, если вы устанавливаете своего демона из приложения с графическим интерфейсом, в macOS 12 «Монтерей» или более ранней версии SMJobBless
— это даже лучшее решение, чем выбор местоположения вручную и добавление plist в /Library/LaunchDaemons
.
Для macOS 13 «Ventura» и новее ознакомьтесь с разделом о демонах и агентах в сеансе WWDC22 «Что нового в конфиденциальности» и с новыми API SMAppService, доступными там.
Вот несколько идей: (1) это действительно приложение, например, использующее Cocoa и вызывающее
NSApplicationMain()
? Если это так, я не думаю, что вы получите много удовольствия от запуска этого демона запуска. (ЛаунчАгент Логинвиндова был бы более подходящим для этого случая) (2) Включены ли у вас зашифрованные домашние каталоги? (3) Является ли приложение песочницей? (4) Пробовали ли вы разместить приложение в более общем месте, например, в/Applications/
?