复制到剪贴板的文件为空,粘贴时“丢失沙盒扩展”

时间:2013-11-13 14:36:33

标签: objective-c macos cocoa osx-mavericks appkit

我有一个将文件复制到剪贴板的应用程序。以下是相关代码(参数是包含文件路径的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中的空电子邮件时进行测试时,通常该文件显示为零字节,并且控制台上会显示以下错误:

  

11/13/13 6:27:12.173 AM邮件[627]:无法从粘贴板获取有关[:789514] of flavor:[public.file-url]的有效沙盒扩展名。   11/13/13 6:27:12.174 AM邮件[627]:无法获得itemIdentifier(789514)的沙箱扩展。沙箱扩展的数据为NULL

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

  

11/13/13 8:24:41.947 AM sandboxd [172] :( [627])邮件(627)拒绝file-read-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 picture,4197954},{«class PNGf»,392648},{«class jp2»,213480},{GIF picture,121307},{ JPEG图片,116181},{Unicode文字,110},{string,55}}

因此,Finder会在剪贴板上提供有关该文件的更多信息以及不同的信息。例如,furl类具有不同的长度。这些额外的信息显然是什么原因导致Mail成功通过从Finder复制的文件,因为它错误地粘贴了我的程序复制的文件。

当我将文件放在剪贴板上或者我应该向粘贴添加哪些额外信息时,我缺少哪些信息的线索?我猜测Finder不只是粘贴一个NSURL数组,而是一个包含其他文件信息的字典键数组。它似乎也创造了与我不同的furl类。我花了很多时间来阅读文档而且我坚持这个。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

但所有的答案都没有最明显的可以触发沙盒的问题。

当您将 NSURL(仍然基于 NSString)复制到 NSPasteboard 中时 没有正确转义的字符在转换为“NSURL”之前仍然包含无效符号和空格

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

它只是说:

<块引用>

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

那么你必须用

正确地转义字符串
NSString *encodedStringForURL = [yourString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

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

<块引用>

未能获得有效的沙箱扩展

那么您还使用了错误的 NSPasteboardType,它暴露了一个没有正确类型的 URL。例如,当您暴露一个字符串作为链接时,因为您试图通过聪明地告诉粘贴板这一个随机字符串来避免 [沙盒] 触发器。当您在字符串前加上 file:// 时,沙箱仍然更聪明。

那么解决方案是使用 NSPasteboardTypeFileURL 和/或 NSPasteboardTypeURL。这将通知沙箱您有意公开了正确类型的链接。

有更多陷阱,但请记住,粘贴到 Pasteboard 时必须使用 YourURL.absoluteString