使用NSTask启动可执行文件 - 沙盒问题?

时间:2013-07-21 15:11:47

标签: objective-c cocoa

我有一个Mac OSX应用程序,它启动位于/ Contents / Resources中的可执行文件。 该应用程序不打算在App Store上发布,因此我没有打开沙箱。

启动代码:

toolPath = [[[NSBundle mainBundle] pathForResource:@"myexecutable" ofType:@""] copy];
task = [[NSTask alloc] init];
[task setLaunchPath: toolPath];
pipe = [[NSPipe alloc] init];
[task setArguments:[NSArray arrayWithObjects:@"-someArg", someVariable, nil]];
file = [[NSFileHandle alloc] initWithFileDescriptor:[pipe fileHandleForReading].fileDescriptor];
[task setStandardOutput: stderrPipe];
[task launch];

事情是 - 在Xcode中运行时,一切正常。 将应用程序导出到桌面并运行它时,它也可以正常工作。

但是,如果我将应用程序压缩,将其上传到网络服务器,然后在同一台计算机上下载(或将其下载到另一台Mac),则该任务不再启动!我在系统控制台或其他任何地方都没有错误。

我研究了一些关于这个问题的内容,发现OSX将新的应用标记为“隔离”特殊许可权。所以我调查了下载的应用程序和导出的应用程序之间的区别:

从Xcode导出我的应用程序后可执行文件的权限:

-rwxr-xr-x  1 Username  staff   65724 21 Jul 16:31 executableName

此时应用程序正常运行,可执行文件从应用程序内的按钮启动。

压缩应用程序后,上传到服务器,下载,解压缩,打开应用程序并接受“此应用程序已从Internet下载”对话框:

-rwxr-xr-x  1 Username  staff   65724 21 Jul 16:31 executableName
    com.apple.quarantine        26 

此时我在应用程序中按下按钮时没有任何反应。

如果我在整个应用上运行xattr -rd com.apple.quarantine,则会删除隔离通知:

-rwxr-xr-x  1 Username  staff   65724 21 Jul 16:31 executableName

但可执行文件尚未启动!

此时我现在在桌面应用上拥有以下权限:

/内容/ MacOS的:

-rwxr-xr-x  1 Username  staff  407728 21 Jul 16:31 appName

/内容/资源:

-rwxr-xr-x  1 Username  staff   65724 21 Jul 16:31 executableName

在下载的应用程序中,我使用了xattr -rd:

/内容/ MacOS的:

-rwxr-xr-x  1 Username  staff  407728 21 Jul 16:31 appName

/内容/资源:

-rwxr-xr-x  1 Username  staff   65724 21 Jul 16:31 executableName

第一个应用程序正常工作,第二个应用程序永远不会启动可执行文件。到底他妈发生了什么?它是相同的应用程序,在同一台计算机上,具有相同的权限,但下载的只是不起作用。

此问题出现在不同计算机上的所有OSX版本中。

2 个答案:

答案 0 :(得分:7)

com.apple.security.inherit 权利添加到帮助应用程序为我解决了这个问题。

当我尝试使用NSTask启动时,我的助手应用程序曾与Could not set sandbox profile data: Operation not permitted (1)崩溃。

来自Apple文档的

  

如果您的应用程序使用使用posix_spawn函数或NSTask类创建的子进程,则可以将子进程配置为继承其父进程的沙箱。但是,使用子进程不能提供使用XPC服务所提供的安全性。

  要启用沙箱继承,子目标必须使用两个App Sandbox授权密钥: com.apple.security.app-sandbox com.apple.security.inherit 。如果指定任何其他App Sandbox权利,系统将中止子进程。但是,您可以通过iCloud和通知权利为子进程提供其他功能。

  Xcode项目中的主应用程序必须永远不具有继承权利的YES值。

我希望这个解决方案有所帮助。

答案 1 :(得分:1)

我终于找到了导致这个问题的原因, 尝试使用写入文件的NSTask启动可执行文件时发生了这种情况。 奇怪的是,这在原始帖子中提到的某些情况下工作正常。 但为了让它在其他计算机上工作,我最终使用STPrivilegedTask来解决问题。