如何以与Finder相同的方式删除当前用户不拥有的项目?

时间:2019-06-24 13:07:02

标签: macos filesystems nsfilemanager nsworkspace

我正在编写一个工具,该工具提供了对选定项目(文件,文件夹)进行垃圾回收的选项。通常,对于每个项目,我都会打电话给-[NSFileManager trashItemAtURL:...],正如thisthis这样的问题中也对此进行了解释。

但是, 在尝试从其他用户拥有的目录(例如root)中删除文件时不起作用 。在这种情况下,我的工具应提供与Finder相同的选项,即要求用户通过提供Admin用户的凭据来授权操作,然后我的应用程序将像Finder一样将项目移至垃圾箱。

我尝试使用特权帮助程序来解决此问题,如EvenBetterAuthorizationSample示例代码所概述,并使用launchdSMJobBless和XPC服务。

但是,问题是特权帮助程序以root用户身份运行,而我的应用程序所运行的当前用户却不知道。结果是,当它对文件进行垃圾回收时, 它最终位于根用户的“垃圾箱”文件夹中,而不是像Finder那样位于用户的“垃圾箱”文件夹中。

我该如何解决,即如何将用户不拥有的项目移至当前用户的回收站,而不是根用户的回收站?

我可以使用一些技巧来让我继续使用现有的垃圾回收器功能之一吗?

我自己进行移动无法正常工作,因为要使放回正常工作,则需要更新垃圾箱的.DS_Store文件,而AFAIK则没有API。

1 个答案:

答案 0 :(得分:1)

我已经几乎找到了解决方案:

分析

运行帮助程序时,例如通过launchd或通过AuthorizationExecuteWithPrivileges(在macOS 10.15下),它可能以root身份运行,而无需登录用户,因此无法确定用户的“废纸'”文件夹。

奇怪的是,环境变量(请参阅man env)甚至可以显示当前用户的名称和主目录,但可以显示{em>真实用户ID ,可以使用getuid()进行查询。 ,将返回0(root),这还会导致NSUserName()NSHomeDirectory()返回root用户的信息。看来trashItemAtURL和相关功能依赖于NSHomeDirectory()来确定垃圾箱文件夹的位置。

半工作解决方案

幸运的是,有一种方法可以使用setreuid更改真实用户ID

因此,在我的测试中,当我调用setreuid (501, 0)(501是当前登录用户的uid)时,trashItemAtURL确实将文件移到了用户的“废纸folder”文件夹中并在必要时自动重命名。

但是,不能使回退正常工作,就像使用Finder删除同一文件一样。

恢复工作

回退不起作用的原因似乎来自一个更深层次的问题:它似乎是macOS框架中的一个长期存在的错误,请参见this bug report

这基本上意味着:这是我们可以最好的利用,直到Apple修复潜在的错误为止。

使回退起作用的唯一可行选择是要求Finder使用AppleEvents / AppleScript丢弃项目。