NSTask介绍,指令、调用外部程序

1,068 阅读2分钟

简介

  • 首先不懂的同学可能想知道NSTask是干嘛的?简单说NSTask对象的作用是启动外部进程、调用外部命令,在C#中类似于Process
  • 其次NSTask可以创建一个当前线程的子进程对象,运行另一个程序,并监视该程序的执行(使用NSPipe,NSFileHandle接收结果)。并且不会与创建它的进程共享内存空间。
  • 进程在运行中不能更改
  • Swift中NSTask更名为Process
  • 你想要运筹帷幄之中,决胜千里之外,NSTask会是你的得力助手

常用方法及属性

@property (nullable, copy) NSString * launchPath设置调用路径
@property (nullable, copy) NSArray<NSString *> *arguments;设置调用参数(被调用程序命令)
标准输入\输出通道,用NSFilehandle或者NSPipe设置接受
@property (nullable, retain) id standardInput;输入信息
@property (nullable, retain) id standardOutput;输出
@property (nullable, retain) id standardError;错误输出

设置输出接受handle
    NSPipe *pipe = [NSPipe pipe];
    [certTask setStandardOutput:pipe];
    [certTask setStandardError:pipe];
    NSFileHandle *handle = [pipe fileHandleForReading];

NSString *securityResult = [[NSString alloc] initWithData:[handle readDataToEndOfFile] encoding:NSASCIIStringEncoding];
//函数输出结果

- (void)launch;开始执行线程(一个线程只能执行一次,之后的调用都会抛出错误异常)
@property (readonly, getter=isRunning) BOOL running;运行状态,是否在运行
@property (readonly) int terminationStatus; 退出状态(判断命令执行是否成功完成)

用法

1.解压缩

终端用法$unzip -q filepath -d despath
使用NSTask在Mac上调用:

    NSTask *unzipTask = [[NSTask alloc] init];
    [unzipTask setLaunchPath:@"/usr/bin/unzip"];
    [unzipTask setArguments:[NSArray arrayWithObjects:@"-q", @"~***.IPA", @"-d", @"~\unzipdirectory", nil]];
    [unzipTask launch];

这样就完成了调用unzip解压一个IPA 到指定路径的命令调用

2.读取签名证书列表

终端命令为$security find-identity -v -p codesigning

    NSTask *certTask = [[NSTask alloc] init];
    [certTask setLaunchPath:@"/usr/bin/security"];
    [certTask setArguments:[NSArray arrayWithObjects:@"find-identity", @"-v", @"-p", @"codesigning", nil]];
    NSPipe *pipe = [NSPipe pipe];
    [certTask setStandardOutput:pipe];
    [certTask setStandardError:pipe];
    NSFileHandle *handle = [pipe fileHandleForReading];
    [certTask launch];

解析崩溃文件

-(void)beginToAnalysisCrashFile {
    NSPipe *pipe = [NSPipe pipe];
    NSFileHandle *file = pipe.fileHandleForReading;
    NSTask *analysisTask = [[NSTask alloc] init];
    /// 获取解析崩溃的应用
    NSString *launchPath = @"/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash";
    if (launchPath==nil||!([launchPath rangeOfString:@"Xcode.app"].length>0)){
        [self AlertViewShowWithMessageText:NSLocalizedString(@"warning", @"")  InforMativeText:NSLocalizedString(@"noXcode", @"") ];
    } else {
        analysisTask.launchPath = launchPath; ///设置调用路径
    }

/// self.crashFilePath:崩溃文件.ips文件,self.dsymlFilePath:符号表.dSYM文件
    NSArray *array = [NSArray arrayWithObjects:self.crashFilePath, self.dsymlFilePath, nil];
    [analysisTask setArguments:array];
    [analysisTask setEnvironment:@{
                                 @"DEVELOPER_DIR":@"/Applications/Xcode.app/Contents/Developer"
                                  }];
    [analysisTask setStandardOutput:pipe];
    [analysisTask launch];
    NSData *data = [file readDataToEndOfFile];
    [file closeFile];

    NSString *LogOutput = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
    if (LogOutput && LogOutput.length > 0){
        dispatch_async(dispatch_get_main_queue(), ^{
            NSString *logoutFilePath = [[**self**.crashFilePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"log"];
            _LogOut = [_LogOut stringByAppendingString:[NSString stringWithFormat:@"%@%@\n",NSLocalizedString(@"finishedAnalyseLog", @""),logoutFilePath]];
            [self.logOutView setString:_LogOut];
        });
    }
//    _LogOut=[_LogOut stringByAppendingString:[NSString stringWithFormat:@"\n%@",LogOutput]];
//    if (_LogOut==nil||[_LogOut isEqualToString:@""]) {
//        _LogOut=@"";
//    }
//    [self.logOutView setString:_LogOut];
//    [self.logOutView scrollRangeToVisible:NSMakeRange(_LogOut.length-1, 1)];
    [self writeToFileWithContent:LogOutput];
}

-(void)writeToFileWithContent:(NSString*)logOut{
    NSString *logoutFilePath = [[self.crashFilePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"log"];
    NSError *error;
    [logOut writeToFile:logoutFilePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
    if (error){
        dispatch_async(dispatch_get_main_queue(), ^{
            [self AlertViewShowWithMessageText:NSLocalizedString(@"alert", @"") InforMativeText:NSLocalizedString(@"errorWriteLog", @"")];
        });
    }else{
        dispatch_async(dispatch_get_main_queue(), ^{
            _LogOut = [_LogOut stringByAppendingString:NSLocalizedString(@"successWriteLog",@"")];
            [self.logOutView setString:_LogOut];
        });
    }
}

-(void)AlertViewShowWithMessageText:(NSString *)message InforMativeText:(NSString*)info{
    NSAlert *alert=[NSAlert alertWithMessageText:message defaultButton:NSLocalizedString(@"confirm",@"") alternateButton:NSLocalizedString(@"cancel",@"") otherButton:nil informativeTextWithFormat: info,nil];
    [alert beginSheetModalForWindow:[NSApplication sharedApplication].keyWindow completionHandler:nil];
}

暂时写这么多,后续空下来继续更新