首页 > 解决方案 > NSWorkspace.OpenConfiguration 忽略参数,尽管没有被沙盒化

问题描述

我正在尝试open通过 Swift 使用该工具启动应用程序。我有两个单独的实现,一个NSWorkspace.shared.openApplication(at:configuration)用于 10.15+,一个NSWorkspace.shared.launchApplication(at:options:configuration)用于 10.14 及更低版本。在 10.14 及以下版本一切正常,但 Catalina 忽略了向它抛出的任何参数。该应用程序没有沙盒化。

10.15+ 的实现:

let appPath = URL(string: "file:///usr/bin/open")!
let configuration = NSWorkspace.OpenConfiguration()
configuration.arguments = [
    "-a",
    executablePath,
    url.absoluteString
]

NSWorkspace.shared.openApplication(at: appPath, configuration: configuration) { (app, error) in
    if let error = error {
        done(error)
    } else {
        done(nil)
    }
}

运行此命令会打开一个不带参数的终端窗口/usr/bin/open,然后关闭会话。

卡特琳娜打开一个终端

executablePath是应用程序可执行文件的字符串,例如/Application/Safari.app/Contents/MacOS/Safari

url是一个包含 http 或 https 链接的 URL 对象

从 appPath 中删除file://在 10.14 中也可以正常工作,但在 10.15 中会导致The application “open” could not be launched because a miscellaneous error occurred.

我错过了什么吗?

标签: swiftcocoamacos-catalinaappkitnsworkspace

解决方案


我以不同的方式解决了这个问题。而不是使用NSWorkspace.shared.openApplication(at:configuration:)我现在调用一个Process打开的open

这也适用于 Catalina 以下的版本,甚至适用于沙盒。但是,沙盒有一个陷阱,请在最后阅读更多内容。

解决方法

let task = Process()
        
task.arguments = ["-a", executablePath, url.absoluteString]
task.launchPath = "/usr/bin/open"
task.launch()

无需等待该过程,因为 a) open 的返回不是那么有用,b) 无论如何它几乎是立即的。

关于沙盒

苹果表示:

在沙盒应用程序中,使用 Process 类创建的子进程会继承父应用程序的沙盒。

这意味着使用打开的应用程序Process具有相同的沙箱。如果您open像我一样使用打开 URL,那很好,因为open无论如何都会在没有我们的沙箱的情况下生成一个新进程。但是,这确实意味着您不能使用此打开的其他常规应用程序,除非此应用程序与您的沙箱一起正常工作。


推荐阅读