【问题标题】:Code to use NSTask with ps to verify a process is running使用 NSTask 和 ps 验证进程是否正在运行的代码
【发布时间】:2013-01-28 18:08:53
【问题描述】:

我在检查屏幕保护程序是否正在运行时遇到了无穷无尽的问题。如果我将NSTaskps 一起使用,它会在很多用户上崩溃或挂起。如果我使用通知,对其他人来说似乎参差不齐。

关于为什么这个 NSTask 是 flakey 的任何想法? (是的,我知道它现在在调试时很乱)

  -(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);
}

【问题讨论】:

  • 您为什么要检查屏幕保护程序进程?你会不会更好地检查屏幕是否被锁定? stackoverflow.com/questions/11505255/…
  • “使用通知”是什么意思?
  • 使用系统范围的通知,例如 com.apple.screensaverstarted。 Petesh,我一定会看看其他的 api

标签: objective-c macos nstask ps


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 2016-05-15
    • 1970-01-01
    相关资源
    最近更新 更多