用例:我以“ user1 ”身份登录并启动Safari,然后单击右上角的“ user1 ”并将用户切换为“ user2 ”。
现在,我正在尝试检测Safari是否针对“ user1 ”运行,但是我无法使用标准调用来执行此操作。我正在使用OS X 10.8 Mountain Lion进行开发和运行我的代码。

我用了以下但徒劳的:

  • [[NSWorkspace sharedWorkspace] runningApplications]-列表
  • 中没有Safari
  • GetNextProcess()-Safari不出现
  • GetProcessForPID()-我收到一个错误“没有这样的过程”

  • 但是,当我从终端上执行ps -aef | grep Safari时,我可以看到Safari。 (不仅在Safari中,而且在其他应用程序中也是如此。)

    有人可以帮忙吗?非常感谢你。

    最佳答案

    您可以使用sysctl或ps命令获取所有BSD进程的列表。

    #include <sys/sysctl.h>
    #include <pwd.h>
    typedef struct kinfo_proc kinfo_proc;
    
    static int GetBSDProcessList(kinfo_proc **procList, size_t *procCount)
    // Returns a list of all BSD processes on the system.  This routine
    // allocates the list and puts it in *procList and a count of the
    // number of entries in *procCount.  You are responsible for freeing
    // this list (use "free" from System framework).
    // On success, the function returns 0.
    // On error, the function returns a BSD errno value.
    {
        int                 err;
        kinfo_proc *        result;
        bool                done;
        static const int    name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };
        // Declaring name as const requires us to cast it when passing it to
        // sysctl because the prototype doesn't include the const modifier.
        size_t              length;
    
        //    assert( procList != NULL);
        //    assert(*procList == NULL);
        //    assert(procCount != NULL);
    
        *procCount = 0;
    
        // We start by calling sysctl with result == NULL and length == 0.
        // That will succeed, and set length to the appropriate length.
        // We then allocate a buffer of that size and call sysctl again
        // with that buffer.  If that succeeds, we're done.  If that fails
        // with ENOMEM, we have to throw away our buffer and loop.  Note
        // that the loop causes use to call sysctl with NULL again; this
        // is necessary because the ENOMEM failure case sets length to
        // the amount of data returned, not the amount of data that
        // could have been returned.
    
        result = NULL;
        done = false;
        do {
            assert(result == NULL);
    
            // Call sysctl with a NULL buffer.
    
            length = 0;
            err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1,
                         NULL, &length,
                         NULL, 0);
            if (err == -1) {
                err = errno;
            }
    
            // Allocate an appropriately sized buffer based on the results
            // from the previous call.
    
            if (err == 0) {
                result = malloc(length);
                if (result == NULL) {
                    err = ENOMEM;
                }
            }
    
            // Call sysctl again with the new buffer.  If we get an ENOMEM
            // error, toss away our buffer and start again.
    
            if (err == 0) {
                err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1,
                             result, &length,
                             NULL, 0);
                if (err == -1) {
                    err = errno;
                }
                if (err == 0) {
                    done = true;
                } else if (err == ENOMEM) {
                    assert(result != NULL);
                    free(result);
                    result = NULL;
                    err = 0;
                }
            }
        } while (err == 0 && ! done);
    
        // Clean up and establish post conditions.
    
        if (err != 0 && result != NULL) {
            free(result);
            result = NULL;
        }
        *procList = result;
        if (err == 0) {
            *procCount = length / sizeof(kinfo_proc);
        }
    
        assert( (err == 0) == (*procList != NULL) );
    
        return err;
    }
    
    + (NSArray*)getBSDProcessList
    {
        kinfo_proc *mylist =NULL;
        size_t mycount = 0;
        GetBSDProcessList(&mylist, &mycount);
    
        NSMutableArray *processes = [NSMutableArray arrayWithCapacity:(int)mycount];
    
        for (int i = 0; i < mycount; i++) {
            struct kinfo_proc *currentProcess = &mylist[i];
            struct passwd *user = getpwuid(currentProcess->kp_eproc.e_ucred.cr_uid);
            NSMutableDictionary *entry = [NSMutableDictionary dictionaryWithCapacity:4];
    
            NSNumber *processID = [NSNumber numberWithInt:currentProcess->kp_proc.p_pid];
            NSString *processName = [NSString stringWithFormat: @"%s",currentProcess->kp_proc.p_comm];
            if (processID)[entry setObject:processID forKey:@"processID"];
            if (processName)[entry setObject:processName forKey:@"processName"];
    
            if (user){
                NSNumber *userID = [NSNumber numberWithUnsignedInt:currentProcess->kp_eproc.e_ucred.cr_uid];
                NSString *userName = [NSString stringWithFormat: @"%s",user->pw_name];
    
                if (userID)[entry setObject:userID forKey:@"userID"];
                if (userName)[entry setObject:userName forKey:@"userName"];
            }
    
            [processes addObject:[NSDictionary dictionaryWithDictionary:entry]];
        }
        free(mylist);
    
        return [NSArray arrayWithArray:processes];
    }
    

    关于objective-c - 无法检测到与其他用户一起运行的应用程序(通过切换用户),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18820199/

    10-14 20:33