SMAppService register():如何检测Mac应用开机登录启动与常规启动?
区分macOS Ventura开机登录启动与手动启动的方法
针对你通过SMAppService.mainApp.register()实现开机启动的场景,这里提供两种可靠的判断方式:
1. 使用SMAppService的launchReason属性(官方推荐)
在macOS 13及以上版本中,SMAppService原生提供了launchReason属性,可直接获取应用的启动触发原因,其中.loginItem就对应开机登录启动的场景:
import ServiceManagement func judgeLaunchType() { let appService = SMAppService.mainApp if appService.launchReason == .loginItem { // 开机登录启动,执行后台专属逻辑(如仅显示菜单栏图标) print("应用通过开机登录启动") } else { // 用户手动启动,执行常规逻辑(如打开主窗口) print("应用由用户手动启动") } }
这是官方提供的最直接、最可靠的判断方式,无需依赖进程或环境变量的间接推测。
2. 检查父进程信息(兼容补充方案)
如果需要兼容更早系统版本,或作为辅助验证手段,可以通过父进程类型判断:
- 开机登录启动的应用,父进程是系统级守护进程
launchd(进程ID固定为1) - 用户手动启动的应用,父进程通常是
Finder、Launchpad,或终端启动时的bash/zsh等
通过NSProcessInfo可以实现这一判断:
import Foundation func isLaunchedByLogin() -> Bool { let parentPID = getppid() let processInfo = NSProcessInfo.processInfo let parentProcessName = processInfo.processName(forPID: parentPID) ?? "" return parentProcessName == "launchd" }
调用该方法返回true时,即可判定为开机登录启动场景。
关键注意点
- 不要尝试通过命令行参数区分:
SMAppService注册的开机启动项不支持传递自定义命令行参数,官方也未提供相关扩展能力。 - 避免使用临时文件标记:这种方式可能因权限、文件清理等问题出现判断错误,可靠性远低于上述两种方法。
内容的提问来源于stack exchange,提问作者Mark Mc
相关产品推荐
相关产品推荐

