How to catch error when setting launchpath in NSTask

那年仲夏 提交于 2019-12-30 18:01:11

问题


I am trying to run a commandline tool using swift 2 on a mac (10.10):

let task = NSTask()
task.launchPath = "/path/to/wrong/binary"
task.launch()

// NSPipe() stuff to catch output

task.waitUntilExit()

// never reached
if (task.terminationStatus != 0){
    NSLog("uh oh")
}

Since the path is wrong, my program dies with launch path not accessible. However, I don't know, how to catch this error. Using do { try } catch {} around task.launch() does not work, because it does not throw an exception, looking at the terminationStatus is also not working, since it is never reached.

How can I catch a wrong launchPath?

Apple Swift version 2.1.1 (swiftlang-700.1.101.15 clang-700.1.81) Target: x86_64-apple-darwin14.5.0


回答1:


unfortunately, there is no chance to catch runtime exceptions. with try / catch you can recovery from trowing error, not from runtime exception. you can create you own exception handler, but you are still not able to recover from it. try to lunch from NSTask some common shell with command as a parameter and next use a pipe to return os errors to you own code.

import Foundation

let task = Process()
let pipe = Pipe()
task.launchPath = "/bin/bash"
task.arguments = ["-c","unknown"]
task.standardOutput = pipe
task.launch()
let handle = pipe.fileHandleForReading
let data = handle.readDataToEndOfFile()
let dataString = String(data: data, encoding: .utf8)
print(dataString ?? "")

will print

/bin/bash: unknown: command not found



回答2:


In Mac OS X High Sierra, launch() is deprecated. You would use run() instead:

let process = Process()
// ...

do {
    process.run()
} catch let error as NSError {
    print(error.localizedDescription)
    // ...
}

Also have a look at the Apple Dev Docs




回答3:


You're not supposed to catch it. Your computer, the local environment that you app is running in, is deemed as a reliable medium. Therefore, NSTask is designed to expect that any path you feed it is guaranteed to exist. This holds up fine as folks are usually using NSTask to launch standard system executables (bash, diff, rsync, etc...). The crash on an mistyped path is meant to help you find bugs in your code easily. If you're launching your own custom-built binaries embedded in the app's bundle, you should really be using XPC instead.

If you absolutely need to use NSTask to launch unreliable paths, before you create your object, you need to validate the path manually using NSFileManager's fileExistsAtPath(_:isDirectory:) and react accordingly. If even the POSIX permissions flags are unreliable (at which point, your app likely has some serious security problems; if this is a consumer application project, I recommend you rethink your design), you'll also want to check the file's NSFilePosixPermissions attribute to make sure it's executable.



来源:https://stackoverflow.com/questions/34420706/how-to-catch-error-when-setting-launchpath-in-nstask

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!