无法检测到与其他用户一起运行的应用程序(通过切换用户) [英] unable to detect application running with another user (via switch user)

查看:122
本文介绍了无法检测到与其他用户一起运行的应用程序(通过切换用户)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

用例:我以" user1 "身份登录并启动Safari,然后单击右上角的" user1 "并切换用户" user2 ". 现在,我试图检测Safari是否正在为" user1 "运行,但是我无法通过标准调用来运行.我正在使用OS X 10.8 Mountain Lion进行开发和运行我的代码.

Use case: I login as "user1" and launch Safari, then I click "user1" on top-right corner and switch user to "user2". Now, I am trying to detect whether Safari is running for "user1" but I am unable to do so with standard calls. I am using OS X 10.8 Mountain Lion for both development and running my code.

我用了以下但徒劳的:

  1. [[NSWorkspace sharedWorkspace] runningApplications]-列表中没有Safari
  2. GetNextProcess()-Safari无法启动
  3. GetProcessForPID()-我收到错误消息没有这样的过程"
  1. [[NSWorkspace sharedWorkspace] runningApplications] - Safari not there in the list
  2. GetNextProcess() - Safari does not come up
  3. GetProcessForPID() - I get an error "no such process"

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

But when I do a ps -aef | grep Safari from the terminal, I can see Safari. (This is not only the case with Safari but other applications as well.)

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

Can someone please help. Thank you very much.

推荐答案

您可以使用sysctl或ps命令获取所有BSD进程的列表. com/legacy/library/qa/qa2001/qa1123.html>技术问答QA1123

You can use sysctl or ps command to get a list of all BSD processes.Have a look at Technical Q&A QA1123

#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];
}

这篇关于无法检测到与其他用户一起运行的应用程序(通过切换用户)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆