6

我有一个将文件复制到剪贴板的应用程序。这是相关代码(参数是包含文件路径的 NSStrings 数组):

NSMutableArray *filesToCopy = [[NSMutableArray alloc] init];        
int i;
for (i=1; i < [arguments count]; i++) {
    NSString* pathToFile = [arguments objectAtIndex:i];
    NSURL* fileURL = [[NSURL alloc] initFileURLWithPath:pathToFile];
    [filesToCopy addObject:fileURL];
}

NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
NSInteger changeCount = [pasteboard clearContents];
BOOL OK = [pasteboard writeObjects:filesToCopy];

但是,在测试中,尝试将程序复制到剪贴板的文件粘贴到 Mail 中的空电子邮件中时,该文件通常显示为零字节,并且控制台上会出现以下错误:

2013 年 11 月 13 日上午 6:27:12.173 邮件 [627]:无法从粘贴板获取项目的有效沙盒扩展:[789514] of flavor:[public.file-url]。2013 年 11 月 13 日上午 6:27:12.174 邮件 [627]:无法获取 itemIdentifier (789514) 的沙箱扩展。沙盒扩展的数据为 NULL

然后控制台上出现以下错误:

2013 年 11 月 13 日上午 8:24:41.947 沙盒 [172]:([627])邮件(627)拒绝文件读取 xattr [文件的完整路径]

奇怪的是,如果我从 Finder 复制文件,那么它每次都粘贴得很好,没有错误。换句话说,Finder 以某种方式将文件复制到剪贴板,其中的信息与我的操作方式不同。为了验证这一点,我做了一个简单的 AppleScript 来返回剪贴板信息。将文件复制到剪贴板后,返回以下内容:

{{«class furl», 115}, {«class utf8», 115}, {«class ut16», 232}, {string, 115}, {Unicode text, 230}}

在我使用 Finder 将相同的文件复制到剪贴板后,Applescript 返回以下内容:

{{«class furl», 33}, {«class icns», 795020}, {«class ut16», 112}, {«class utf8», 55}, {«class 8BPS», 1630436}, {«class BMP », 4194358}, {«class TPIC», 1059291}, {TIFF 图片, 4197954}, {«class PNGf», 392648}, {«class jp2 », 213480}, {GIF 图片, 121307}, {JPEG 图片, 116181},{Unicode 文本,110},{字符串,55}}

因此 Finder 将有关文件的更多信息和不同的信息放在剪贴板上。例如,furl 类具有不同的长度。这些额外的信息显然是导致 Mail 成功粘贴从 Finder 复制的文件的原因,而它在粘贴由我的程序复制的文件时出错。

当我将文件放在剪贴板上时我丢失了哪些信息或我应该在粘贴中添加哪些额外信息的任何线索?我猜 Finder 不仅粘贴了 NSURL 的数组,还粘贴了包含其他文件信息的字典键数组。它似乎也以与我不同的方式创建了 furl 类。我花了很多时间翻阅文档,但我被困在了这个文档上。

4

2 回答 2

2

我相信我找到了问题所在。似乎当命令行应用程序复制到粘贴板时,有一个与沙盒相关的权限没有被转移。复制的文件可以很好地粘贴到任何非沙盒应用程序中,但不能粘贴到沙盒应用程序中。这种情况下的解决方案是创建一个基于 Cocoa 的常规 .app 程序。我仍然不确定如何,但它以正确传输权限的方式复制文件,并且文件可以粘贴到非沙盒和沙盒应用程序中。

于 2013-11-15T12:24:34.873 回答
0

有很多关于避免在沙盒应用程序中触发沙盒机制的文章。

但所有答案都缺乏最明显的可以触发沙盒的麻烦。

当您在转换为 'NSURL' 之前将 a NSURL(仍基于 NSString)的副本复制到NSPasteboard 没有正确转义的字符仍包含无效符号和空格的情况下

这是 URL 可能成为恶意的方式之一,因此您在尝试将链接公开到粘贴板时收到的错误消息并没有告诉您明显的原因是什么,这只是有点烦人。但也许这也是因为“永远不要提供太多信息如何绕过安全屏障”。

它只是说:

[沙盒] CreateSandboxExtensionData 失败:urlData:0x0000000000XYZ 长度:0(-1 表示空)

那么你必须正确地转义字符串

NSString *encodedStringForURL = [yourString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

这将交换不应成为 n URL 一部分的特殊字符。之后,您可以像往常一样转换为 NSURL。

或者

未能获得有效的沙盒扩展

那么你还使用了一个错误NSPasteboardType,它暴露了一个没有正确类型的 URL。例如,当您暴露一个伪装成 Link 的字符串时,因为您试图通过巧妙地告诉粘贴板这只是一个随机字符串来避免 [沙盒] 触发器。当您在字符串前面加上file://.

然后解决方案是使用NSPasteboardTypeFileURL和/或NSPasteboardTypeURL. 这将通知沙盒您故意以正确的类型公开链接。

还有更多的陷阱,但也要记住YourURL.absoluteString在粘贴到粘贴板时必须使用。

于 2021-06-06T18:56:27.660 回答