当用户删除时,卸载由.app安装的项目,包括SMJobBless帮助程序

时间:2016-10-11 15:06:40

标签: macos elevated-privileges launch-daemon smjobbless service-management

简短版本:是否可以删除应用程序删除时由应用程序(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

我能想到的唯一两件事并不令人满意:

  1. 某种卸载程序或脚本。但这看起来也很难看。
  2. 当用户删除我们的应用程序时,不要担心它,只会留下一团糟。

3 个答案:

答案 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从应用程序触发。这就是我们的目标。