我有一个应用程序服务,我想在系统启动时使用 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 我员工 54755728 11 月 29 日 12:46 应用
它运行良好,但不随系统启动 - 它只是将错误记录到 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.
当用户“我”登录并且服务开始工作时,这些错误就会停止。我需要它在没有“我”登录的情况下工作。
有什么想法吗?
最佳答案
根据评论中的讨论,我们已将其范围缩小到路径问题。我在这里并不是 100% 清楚阻止访问的确切机制,但预登录是一个相当锁定的环境,因此我并不感到非常惊讶它无法从用户的桌面文件夹运行。
我怀疑在您的特定情况下,这取决于同意系统:登录用户需要授予每个进程对某些目录的访问权限,例如Desktop
、Documents
、下载
等,并且由于没有用户登录,因此不会记录同意。
如果您的可执行文件位于 .app bundle 内,app translocation将是一个额外的问题。
解决方案是在系统范围内安装启动守护程序或全局启动代理二进制文件。如果它们是 .app bundle 的一部分,请将应用程序安装在 /Applications
中(这也将避免应用程序易位问题)。否则,“好的”位置是 /Library/Application Support/[Your-Application]/
。
顺便说一句,如果您从 GUI 应用程序安装守护程序,则在 macOS 12“Monterey”或更早版本上,SMJobBless
是比手动选择位置并将 plist 放入 /Library/LaunchDaemons
。
对于 macOS 13“Ventura”及更高版本,请查看 section about daemons and agents in the WWDC22 'What's new in Privacy' session和新的SMAppService
那里提供 API。
关于macos - MacOS 上的 LaunchDaemon 服务只有在用户登录后才会运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74664759/