【问题标题】:Interactive access to command using NSTask使用 NSTask 交互式访问命令
【发布时间】:2017-03-13 20:14:37
【问题描述】:

我正在使用一个 NSTask 来运行一个交互式的 cli 应用程序。我用它通过 USB 连接提取数据。

我正在打开一个带有大纲和错误管道的 NSTask,但是当我发出命令时,它可以工作,但会在循环中旋转沙滩球,从输出中提取数据。

我希望能够混合执行帮助命令的 - (IBAction)clicked:(id)sender 按钮并返回输出:

NSTask *usbCommandTask;
NSPipe *outPipe;
NSPipe *inPipe;
NSPipe *errorPipe;
NSFileHandle *inFile;
NSFileHandle *outFile;
NSTimer *pollTimer;
dispatch_queue_t mtpTask;

@implementation AppDelegate


- (void)commandNotification:(NSNotification *)notification
{
    NSData *data = nil;

    while ((data = [outFile availableData]) && [data length]){
        NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"Data: %@",myString);
        }
    NSLog(@"Execution never gets here");

}

-(void)checkTask
{
    if(usbCommandTask){
        if([usbCommandTask isRunning])NSLog(@"Task running"); else NSLog(@"Task dead");

    } else NSLog(@"Task is nil");


}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {



    usbCommandTask = [[NSTask alloc] init];
    [usbCommandTask setLaunchPath:@"/Applications/usb-debugger-cli"];
    [usbCommandTask setCurrentDirectoryPath:@"/"];
    [usbCommandTask setArguments:[NSArray arrayWithObject:@"-i"]];
    inPipe = [NSPipe pipe];
    [usbCommandTask setStandardInput:inPipe];




    outPipe = [NSPipe pipe];
    [usbCommandTask setStandardOutput:outPipe];
    errorPipe = [NSPipe pipe];
    [usbCommandTask setStandardError:errorPipe];

    outFile = [outPipe fileHandleForReading];
    inFile = [inPipe fileHandleForWriting];

     [outFile waitForDataInBackgroundAndNotify];



    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(commandNotification:)
                                                 name:NSFileHandleDataAvailableNotification
                                               object:nil];



    pollTimer=[NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(checkTask) userInfo:nil repeats:TRUE];
    [usbCommandTask launch];
    NSLog(@"Launched");



}


- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
    if(usbCommandTask)[usbCommandTask terminate];


}


- (IBAction)clicked:(id)sender {

    if(usbCommandTask){
    NSString *command=@"help\n";
    NSData *commandData=[NSData dataWithBytes:command.UTF8String length:command.length];

    [inFile writeData:commandData];
    }
    else
    {NSLog(@"Comamnd task dead");
    }
}

【问题讨论】:

    标签: cocoa nstask nspipe


    【解决方案1】:
    [outFile availableData] 
    

    实际上是一个阻塞调用,没有数据或显式EOF,所以这总是会阻塞,而不是我使用:

    data = [outFile availableData];
    NSString *myString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    NSLog(@"Data: %@",myString);
    [outFile waitForDataInBackgroundAndNotify];
    

    【讨论】:

      猜你喜欢
      • 2014-05-08
      • 2012-08-17
      • 2012-03-12
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多