【问题标题】:Getting exit status after launching app with NSWorkspace launchApplicationAtURL使用 NSWorkspace launchApplicationAtURL 启动应用程序后获取退出状态
【发布时间】:2011-03-14 18:14:05
【问题描述】:

我是 Mac 编程的新手。我正在将插件移植到 OSX。我需要我的应用程序启动第二个应用程序(我不控制其源),然后获取其退出代码。 NSWorkspace launchApplicationAtURL 可以很好地使用所需的参数启动它,但我看不到如何获取退出代码。设置终止第二个应用程序的通知后有没有办法获得它?我看到了使用 NSTask 获取退出代码的工具。我应该使用它吗?

【问题讨论】:

    标签: objective-c cocoa macos


    【解决方案1】:

    NSWorkspace 方法真正用于启动独立应用程序;根据文档,使用NSTask“将另一个程序作为子进程运行并......监视该程序的执行”。

    这是一个启动可执行文件并返回其标准输出的简单方法 - 它阻塞等待完成:

    // Arguments:
    //    atPath: full pathname of executable
    //    arguments: array of arguments to pass, or nil if none
    // Return:
    //    the standard output, or nil if any error
    + (NSString *) runCommand:(NSString *)atPath withArguments:(NSArray *)arguments
    {
        NSTask *task = [NSTask new];
        NSPipe *pipe = [NSPipe new];
    
        [task setStandardOutput:pipe];     // pipe standard output
    
        [task setLaunchPath:atPath];       // set path
        if(arguments != nil)
            [task setArguments:arguments]; // set arguments
    
        [task launch];                     // execute
    
        NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile]; // read standard output
    
        [task waitUntilExit];              // wait for completion
    
        if ([task terminationStatus] != 0) // check termination status
            return nil;
    
        if (data == nil)
            return nil;
    
        return [NSString stringWithUTF8Data:data]; // return stdout as string
    }
    

    你可能不想阻塞,特别是如果这是你的主 UI 线程,提供标准输入等。

    【讨论】:

    • 非常感谢!我得到了一个使用 NSTask 的更基本的版本,但这非常有用。我的困惑在于 NSTask 与 NSWorkspace 的相对目的。不知何故,我觉得 NSWorkspace 正在取代 NSTask。
    • 谢谢,最后一行我改成返回 [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease] 因为应用程序崩溃了
    【解决方案2】:

    事实上,NSTask 的这个属性应该可以解决问题:terminationStatus

    来自 Apple 的文档:

    返回接收者的可执行文件返回的退出状态。

    • (int)terminationStatus

    我测试了它,它工作正常。注意测试任务是否先运行,否则会启动异常。

    if (![aTask isRunning]) {
        int status = [aTask terminationStatus];
        if (status == ATASK_SUCCESS_VALUE)
            NSLog(@"Task succeeded.");
        else
            NSLog(@"Task failed.");
    }
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-02-26
      • 1970-01-01
      • 1970-01-01
      • 2020-04-02
      • 1970-01-01
      • 2011-05-23
      • 2021-10-18
      相关资源
      最近更新 更多