Служба LaunchDaemon в MacOS не работает, пока пользователь не войдет в систему

У меня есть служба приложений, которую я хочу запустить при запуске системы с файлом 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.

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

есть идеи?

Вот несколько идей: (1) это действительно приложение, например, использующее Cocoa и вызывающее NSApplicationMain()? Если это так, я не думаю, что вы получите много удовольствия от запуска этого демона запуска. (ЛаунчАгент Логинвиндова был бы более подходящим для этого случая) (2) Включены ли у вас зашифрованные домашние каталоги? (3) Является ли приложение песочницей? (4) Пробовали ли вы разместить приложение в более общем месте, например, в /Applications/?

pmdj 03.12.2022 11:01

Это основное консольное приложение dotnet. У него нет собственного пользовательского интерфейса, только веб-сервер. 2 нет 3 нет 4 нет еще нет Вы думаете, что это будет иметь значение?

Sean 03.12.2022 13:01

Хорошо, для веб-сервиса LaunchDaemon имеет смысл. Я думаю, что (4) стоит попробовать. Чтобы уточнить, это в комплекте .app? Потому что ошибки предполагают, что это так, но путь предполагает, что это не так. Если это пакет .app, проблема также возникает с переносом приложений. Я не очень хорошо знаком с тем, как dotnet работает с macOS — является ли ваша программа настоящим исполняемым двоичным файлом macOS (Mach-O) или она запускает среду выполнения, которая загружает сборку dotnet, содержащую код? Если это что-то иное, чем собственный двоичный файл, возможно, он не сможет найти другие файлы, необходимые для запуска.

pmdj 03.12.2022 15:55

Это собственный двоичный файл

Sean 03.12.2022 22:24

@pmdj, поэтому кажется, что его установка в /Applications/ решает проблему. По какой-то причине наличие его в каталоге Users означает, что он не может его запустить, что странно, поскольку я думал, что LaunchDaemon работает от имени пользователя root? Но ничего, большое спасибо за идею!

Sean 04.12.2022 05:03

В вашем случае из-за <key>UserName</key> <string>me</string> он не запускается от имени пользователя root, хотя, если имя соответствует Users/me, можно подумать, что это не проблема. Я не совсем уверен, какой механизм предотвращает доступ здесь, но предварительный вход в систему — это странно заблокированная среда, поэтому я не особенно удивлен.

pmdj 04.12.2022 11:36

Я подозреваю, что это связано с системой согласия «Файлы и папки», которая защищает различные подпапки домашнего каталога, такие как «Рабочий стол», «Документы», «Загрузки» и т. д. (см. Панель настроек системы «Безопасность и конфиденциальность»)

pmdj 04.12.2022 11:51
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
7
180
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Из обсуждения в комментариях мы сузили его до проблемы пути. Точный механизм, предотвращающий доступ, здесь мне не ясен на 100%, но предварительный вход — это довольно заблокированная среда, поэтому я не очень удивлен, что он не работает из папки рабочего стола вашего пользователя.

Я подозреваю, что в вашем конкретном случае это сводится к системе согласия: вошедший в систему пользователь должен предоставить каждому процессу доступ к определенным каталогам, таким как Desktop, Documents, Downloads и т. д., и поскольку пользователь не вошел в систему, будет не будет письменного согласия.

Если ваш исполняемый файл находится внутри пакета .app, перенос приложения будет дополнительной проблемой.

Решение состоит в том, чтобы установить демон запуска или глобальные двоичные файлы агента запуска для всей системы. Если они являются частью пакета .app, установите приложение в /Applications (это также позволит избежать проблем с перемещением приложения). В противном случае «хорошее» расположение /Library/Application Support/[Your-Application]/.

Кстати, если вы устанавливаете своего демона из приложения с графическим интерфейсом, в macOS 12 «Монтерей» или более ранней версии SMJobBless — это даже лучшее решение, чем выбор местоположения вручную и добавление plist в /Library/LaunchDaemons.

Для macOS 13 «Ventura» и новее ознакомьтесь с разделом о демонах и агентах в сеансе WWDC22 «Что нового в конфиденциальности» и с новыми API SMAppService, доступными там.

Другие вопросы по теме