简短的版本:可以删除由应用程序(SMJobBless()等)设置的辅助工具吗?当应用程序被删除时?如果是这样的话,是怎么做的?
长篇版本:
不幸的是,我们正在开发的Mac应用程序需要管理员权限来执行偶尔的操作,而且它还需要一个后台任务,以便其他应用程序的插件能够连接到,即使应用本身没有运行(这个可以是非特权的)。该应用程序将使用开发者ID证书签名,并且只在app之外分发。
我们希望这个应用程序尽可能成为一个“好公民”,在卸载时也是如此。
对于后台任务,我们使用使用SMLoginItemSetEnabled()创建的登录项。这并不令人惊讶,因为XPC消息传递似乎不起作用(我们正在使用CFMessagePort --替代建议欢迎),但是如果用户删除了应用程序,登录项至少不会在下一次登录时加载。我怀疑系统中仍然有它的踪迹,但是使用了.app包中的可执行文件,当它消失时,登录项就不再运行了。
对于偶尔需要管理员权限的操作,我们的应用程序使用SMJobBless()安装了一个特权助手工具,它实现了一个名为XPC的服务,因此当它从主应用程序接收到消息时,任务就会按需启动。这就是苹果在其更好的授权示例中所建议和描述的。
助手可执行文件被SMJobBless()复制到SMJobBless()中,嵌入的launchd.plist以/Library/LaunchDaemons/结尾。尽管操作系统有关于哪个应用程序“拥有”助手的信息,但当用户删除应用程序时,它似乎并没有卸载它。苹果的示例对卸载保持沉默,除了uninstall.sh脚本之外,该脚本显然只打算在开发过程中使用。当应用程序没有运行时,我们不需要这个助手,所以将它安装为一个完整的启动守护进程有点过火了,但是我们也希望避免重复使用密码提示来烦扰用户。此外,苹果建议不要使用其他形式的管理权限运行代码,而不是SMJobBless() --例如,SMJobSubmit()被标记为弃用。
那我们该怎么收拾自己呢?
我已经找到了SMJobRemove(),但是(a)在我们的例子中,什么时候才能称之为--您不能在.app包删除上运行代码,或者可以吗?(b) 它似乎并没有被清理干净。
我唯一能想到的两件事并不是特别令人满意:
发布于 2016-11-11 14:28:19
更新:
macOS 13.0Ventura在这方面做了一些改变,介绍了新的机制在WWDC22会话“隐私方面的新事物”中。新的SMAppService API支持对守护进程、代理和登录项的自动清理。不幸的是,您仍然需要为您支持的任何旧的macOS版本找到解决办法。
原来的答案:
在https://forums.developer.apple.com/thread/66821的Apple论坛上也有类似的问题--苹果的建议是手动卸载机制,如果用户不这样做,则消耗尽可能少的资源。
Apple的工作人员进一步建议在特权启动守护进程中实现一种自卸载机制,通过XPC从应用程序中触发。这就是我们要做的。
发布于 2016-10-11 22:44:39
我认为您现在唯一的解决方案是使用您提到的卸载shell代码,以便物理地将特权助手从磁盘中删除,或者为其构建一个卸载程序。无论哪种方式,您都必须要求用户输入他/她的密码。这是所有需要对系统的特权访问的安装程序/卸载程序所做的事情,并且有一个很好的理由。这就是为什么我避免像瘟疫一样使用特权帮手,但我明白有时候你真的必须这么做。我不认为在用户的系统中留下这样的助手是不好的,因为下次用户启动计算机时它会重新加载。
我刚刚检查了ServiceManagement.h头文件,它们声明SMJobRemove将被将来通过libxpc提供的API所取代。(有时,您确实需要转到页眉处,以获得文档没有提供的额外信息。)希望这个承诺的替代将为我们卸载它。但是,我会提交一个bug报告并要求进行增强。
发布于 2016-10-25 03:47:11
您可以考虑的一个解决方案是在.app包中包含一个卸载脚本或程序。
然后,您可以将这个小工具的路径传递给您的助手工具(通过IPC),并让执行卸载程序,从而删除自身。您必须小心,以正确的顺序移除组件,但可以使其工作。
https://stackoverflow.com/questions/39980495
复制相似问题