NSTask: 启动应用程序时出现错误13的posix_spawn。

6

我在我的Swift应用程序中有一个子应用程序。我让它在构建主应用程序时自动复制到Resources文件夹中。这样,我希望能够从主应用程序启动子应用程序的实例。

问题是,我遇到了一个很难调试/找到答案的错误。

以下是我的代码:

    let args = ["--args", "-admin_url", site.url, "-login", site.login, "-pass", site.password]
    let helperPath = (NSBundle.mainBundle().pathForResource("App Helper", ofType: "app"))!
    let task = NSTask.init()
    task.launchPath = helperPath
    task.arguments = args
    task.launch()

还有一个错误:

[56490:7218926] Couldn't posix_spawn: error 13

我不知道该去哪里查找,也不知道该搜索什么。我不知道自己做错了什么。 我在想问题是否与子应用本身有关。目前该子应用为空。我将Application is Agent设置为YES。在MainMenu.xib中,我将Visible at launch选项设置为否。 该子应用需要在后台执行一些工作,并且根本不需要任何 UI。 谢谢!

“Error 13” 是 “Permission Denied” 的错误。你的 helperPath 是什么?如果它不是 /usr/bin,你将会得到这个错误。 - Mtoklitz113
2个回答

2
"launch() 函数已弃用,请使用 run() 函数。"
func shell(_ command: String) -> String {
  let task = Process()
  task.launchPath = "/usr/bin/"
  task.arguments = ["-c", command]
  
  let pipe = Pipe()
  task.standardOutput = pipe
  
  if #available(macOS 10.13, *) {
    try? task.run()
  } else {
    task.launch()
  }
  
  let data = pipe.fileHandleForReading.readDataToEndOfFile()
  let output: String = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String
  
  return output
}


或者使用swift-commands
import Commands

Commands.Bash.run("say hello")

有趣的是,这个解决方案对我很有效,但我没有收到任何弃用警告。 - Confuseious

2
不要使用 NSTask ,应该使用 NSWorkspace
let helperAppURL = NSBundle.mainBundle().URLForResource("App Helper",
                                      withExtension:"app")!

_ = try? NSWorkspace.sharedWorkspace().openURL(helperAppURL,
       options:[.Default],
   configuration:[NSWorkspaceLaunchConfigurationArguments :
            ["--args", "-admin_url", site.url, "-login",
             site.login, "-pass", site.password]])

在上述代码中,为了简洁起见,我忽略了openURL()命令的结果,但实际上它可以返回一个表示任务的NSRunningApplication实例。
为了跟踪您启动的助手应用程序的实例,您可以将这个NSRunningApplication的引用保存在适当类型的集合类中,并在必要时调用其terminate()方法。

这个可以正常工作,谢谢。但我不确定它是否与我需要做的兼容。我需要能够启动应用程序助手的几个实例(我认为这是可以的),并以编程方式终止给定的实例。任务确实有一个terminate()方法。我能否使用openURL()执行等效操作? - Link14
是的,你应该能够使用openURL(_:options:configuration:)来做类似的事情。正在更新答案... - NSGod
NSWorkspace在Catalina及以上版本中存在问题。 - Grzegorz Krukowski
使用进程是首选。https://www.appsloveworld.com/swift/100/65/nsworkspace-openconfiguration-ignores-arguments-despite-not-being-sandboxed - Grzegorz Krukowski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接