使用NSTask和ps验证进程正在运行的代码

时间:2013-01-28 18:08:54

标签: objective-c macos nstask ps

我在查看屏幕保护程序是否正在运行时遇到了无穷无尽的问题。如果我使用NSTask ps,则会崩溃或挂起很多用户。如果我使用通知,那么对其他人来说似乎很不稳定。

关于为什么这个NSTask很有趣的任何想法? (是的,我知道现在调试时很麻烦)

  -(BOOL)checkScreenSaverRunning
{
    MYLog(@"Building task to check screen saver running");
    BOOL foundSaver=FALSE;

    NSTask *task;
    int i;
    task = [[NSTask alloc] init];
    [task setLaunchPath: @"/bin/ps"];

    NSArray *arguments;
    arguments = [NSArray arrayWithObjects:  @"-ax", nil];
    [task setArguments: arguments];

    NSPipe *stdpipe;
    stdpipe = [NSPipe pipe];
    [task setStandardOutput: stdpipe];
    NSFileHandle *stdfile;
    stdfile = [stdpipe fileHandleForReading];
    MYLog(@"Launching task to check screen saver running");
    [task launch];

    while ([task isRunning]){
        NSData *stddata;
        stddata = [stdfile readDataToEndOfFile];
        if([stddata length]>0){
            NSString *stdstring = [[NSString alloc] initWithData:stddata
                                            encoding:NSUTF8StringEncoding];
            NSArray *stdReturnValues=[stdstring componentsSeparatedByString:@"\n"];

            for(i=0;i<[stdReturnValues count];i++){

                if([[stdReturnValues objectAtIndex:i]
                     rangeOfString:@"ScreenSaverEngine"].location != NSNotFound){
                    foundSaver=TRUE;
                    MYLog(@"Found screensaver in running processes");
                }
            }
            [stdstring release];
            stdstring=nil;
        }
    }
    MYLog(@"Task ended");
    [task release];
    if(foundSaver)screenSaverIsActive=TRUE;
    else screenSaverIsActive=FALSE;
    return(foundSaver);
}

1 个答案:

答案 0 :(得分:1)

想知道屏幕保护程序是否正在运行的更高级别目的是什么?可能有更好的方法来实现这一目标。

如果您正在尝试诊断崩溃或挂起,请显示崩溃或挂起报告。

无论如何,如果您要为此生成子流程,则应该使用killall -0 ScreenSaverEngine而不是pskillall会为您找到一个名称的流程。使用信号0(-0)意味着“只测试过程存在,不要实际发出信号”。请[task setStandardError:[NSFileHandle fileHandleWithNullDevice]]确保其输出无处可去。您可以通过在任务终止后检查任务的成功或失败状态来确定该进程是否存在。