我正在编写一个工具,该工具提供了对选定项目(文件,文件夹)进行垃圾回收的选项。通常,对于每个项目,我都会打电话给-[NSFileManager trashItemAtURL:...]
,正如this和this这样的问题中也对此进行了解释。
但是, 在尝试从其他用户拥有的目录(例如root)中删除文件时不起作用 。在这种情况下,我的工具应提供与Finder相同的选项,即要求用户通过提供Admin用户的凭据来授权操作,然后我的应用程序将像Finder一样将项目移至垃圾箱。
我尝试使用特权帮助程序来解决此问题,如EvenBetterAuthorizationSample
示例代码所概述,并使用launchd
,SMJobBless
和XPC服务。
但是,问题是特权帮助程序以root用户身份运行,而我的应用程序所运行的当前用户却不知道。结果是,当它对文件进行垃圾回收时, 它最终位于根用户的“垃圾箱”文件夹中,而不是像Finder那样位于用户的“垃圾箱”文件夹中。
我该如何解决,即如何将用户不拥有的项目移至当前用户的回收站,而不是根用户的回收站?
我可以使用一些技巧来让我继续使用现有的垃圾回收器功能之一吗?
我自己进行移动无法正常工作,因为要使放回正常工作,则需要更新垃圾箱的.DS_Store
文件,而AFAIK则没有API。
答案 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丢弃项目。