简短版本:是否可以删除应用程序删除时由应用程序(SMJobBless()
等)设置的帮助工具?如果是这样,怎么样?
长版:
我们正在开发的Mac应用程序不幸需要管理员权限才能执行偶尔的操作,并且即使应用程序本身没有运行,它也需要后台任务才能连接到其他应用程序的插件(这个可以没有特权)。该应用程序将使用开发者ID证书进行签名,并且仅在App Store外部分发。
我们希望该应用尽可能成为“好公民”,同时也是卸载。
对于后台任务,我们使用的是使用SMLoginItemSetEnabled()
创建的登录项。这并不奇怪,因为XPC消息似乎不起作用(我们使用CFMessagePort
代替 - 欢迎备选建议),但如果用户删除了应用程序,则登录项至少不会被加载下次登录时再见。我怀疑它在系统中的某处仍然存在痕迹,但是使用了.app包中的可执行文件,当它消失时,登录项不再运行。
对于偶尔需要管理员权限的操作,我们有一个特权帮助工具,我们的应用程序使用SMJobBless()
安装,并实现了一个命名的XPC服务,因此任务在收到消息时按需旋转来自主应用程序。这就是Apple在其Even Better Authorization Sample中推荐和描述的内容。
帮助程序可执行文件由/Library/PrivilegedHelperTools/
复制到SMJobBless()
,嵌入式launchd.plist最终在/Library/LaunchDaemons/
。即使操作系统有关于哪个应用程序“拥有”帮助程序的信息,但是当用户删除应用程序时,它似乎不会卸载它。除了显然仅用于开发期间的uninstall.sh
脚本之外,Apple的样本在卸载时保持沉默。当应用程序没有运行时我们不需要这个助手,所以将它安装为一个完整的启动守护程序有点矫枉过正,但我们也希望避免用密码提示反复烦扰用户。此外,Apple建议不要使用管理员权限运行其他形式的代码,而不是SMJobBless()
- 例如,SMJobSubmit()
被标记为已弃用。
那么我们如何清理自己呢?
我找到了SMJobRemove()
,但是(a)在我们的情况下我们何时会调用它 - 你无法在.app包删除上运行代码,或者你可以吗? (b)it doesn't actually seem to clean up。
我能想到的唯一两件事并不令人满意:
答案 0 :(得分:1)
您可以考虑的一个解决方案是在.app包中包含卸载程序脚本或程序。
然后,您可以将此小工具的路径传递给您的帮助工具(通过IPC)并执行卸载程序,从而删除自身。您必须小心,组件将按正确的顺序删除,但可以使其正常工作。
答案 1 :(得分:0)
我认为您现在唯一的解决方案是使用您提到的卸载shell代码,以便从磁盘中物理删除特权帮助程序或为其构建卸载程序。无论哪种方式,您都必须要求用户输入他/她的密码。这就是所有需要特权访问系统的安装程序/卸载程序所做的事情,这是有充分理由的。这就是为什么我像瘟疫一样避免使用特权助手,但我明白,有时你真的必须这样做。我不认为你在用户的系统中留下这样的帮助是好的,因为它会在用户下次启动计算机时重新加载。
我刚检查了ServiceManagement.h标头,他们声明SMJobRemove将被将来通过libxpc提供的API替换。 (有时你真的需要去标题获取文档没有给你的额外信息。)希望这个承诺的替换将为我们卸载它。但是,我提交了一份错误报告,并要求进行改进。
答案 2 :(得分:0)
在https://forums.developer.apple.com/thread/66821的Apple开发者论坛上也出现了类似的问题 - Apple的建议是一种手动卸载机制,如果用户不这样做,则会消耗尽可能少的资源。
Apple DTS员工进一步建议在特权启动守护程序中实现自卸载机制,通过XPC从应用程序触发。这就是我们的目标。