Программно проверить, запущен ли процесс на Mac - PullRequest
11 голосов
/ 25 марта 2010

Есть ли какой-либо API-интерфейс Carbon / Cocoa / C, доступный на Mac, который я могу использовать для перечисления процессов?Я ищу что-то вроде EnumProcesses в Windows.

Моя цель - проверить из кода, запущен ли процесс (по имени).

Спасибо!

Ответы [ 4 ]

15 голосов
/ 22 сентября 2010

Вот некоторые конкретные реализации и подробности, обратите внимание, что proc-> kp_proc.p_comm имеет ограничение длины символов, поэтому я реализовал infoForPID: вместо

Какао:

[NSWorkspace launchApplications] (10.2+, устарело в 10.7, очень ограниченный список процессов) [NSWorkspace runningApplications] (10.6+, менее ограниченный список процессов, но все еще не включая процессы-демоны)

Углерод:

- (NSArray*)getCarbonProcessList
{
    NSMutableArray *ret = [NSMutableArray arrayWithCapacity:1];
    ProcessSerialNumber psn = { kNoProcess, kNoProcess };
    while (GetNextProcess(&psn) == noErr) {
        CFDictionaryRef cfDict = ProcessInformationCopyDictionary(&psn,  kProcessDictionaryIncludeAllInformationMask);
        if (cfDict) {
            NSDictionary *dict = (NSDictionary *)cfDict;
            [ret addObject:[NSDictionary dictionaryWithObjectsAndKeys:
                            [NSString stringWithFormat:@"%@",[dict objectForKey:(id)kCFBundleNameKey]],@"pname",
                            [NSString stringWithFormat:@"%@",[dict objectForKey:@"pid"]],@"pid",
                            [NSString stringWithFormat:@"%d",(uid_t)getuid()],@"uid",                                               
                            nil]]; 
            CFRelease(cfDict);          
        }
    }
    return ret;
}

C: (см. Технические вопросы и ответы QA1123 Получение списка всех процессов в Mac OS X )

- (NSArray*)getBSDProcessList
{
    NSMutableArray *ret = [NSMutableArray arrayWithCapacity:1];
    kinfo_proc *mylist;
    size_t mycount = 0;
    mylist = (kinfo_proc *)malloc(sizeof(kinfo_proc));
    GetBSDProcessList(&mylist, &mycount);
    int k;
    for(k = 0; k < mycount; k++) {
        kinfo_proc *proc = NULL;
        proc = &mylist[k];
        NSString *fullName = [[self infoForPID:proc->kp_proc.p_pid] objectForKey:(id)kCFBundleNameKey];
        if (fullName == nil) fullName = [NSString stringWithFormat:@"%s",proc->kp_proc.p_comm];
        [ret addObject:[NSDictionary dictionaryWithObjectsAndKeys:
                        fullName,@"pname",
                        [NSString stringWithFormat:@"%d",proc->kp_proc.p_pid],@"pid",
                        [NSString stringWithFormat:@"%d",proc->kp_eproc.e_ucred.cr_uid],@"uid",                                               
                        nil]];                                            
    }
    free(mylist);  
    return ret;
}

- (NSDictionary *)infoForPID:(pid_t)pid 
{
    NSDictionary *ret = nil;
    ProcessSerialNumber psn = { kNoProcess, kNoProcess };
    if (GetProcessForPID(pid, &psn) == noErr) {
        CFDictionaryRef cfDict = ProcessInformationCopyDictionary(&psn,kProcessDictionaryIncludeAllInformationMask); 
        ret = [NSDictionary dictionaryWithDictionary:(NSDictionary *)cfDict];
        CFRelease(cfDict);
    }
    return ret;
}
9 голосов
/ 25 марта 2010

TechZen говорит: Менеджер процессов по состоянию на декабрь 2013 г. полностью устарел.

Ах, я только что нашел ссылку Process Manager

Похоже, GetNextProcess и GetProcessInfo помогают выяснить, что работает. По предложению Дейва, GetBSDProcessList можно использовать, если вы ищете демонов, а не только процессы Carbon / Cocoa.

7 голосов
/ 25 марта 2010

Есть несколько способов сделать это:

  1. Если это приложение с графическим интерфейсом со значком Dock, используйте -[NSWorkspace launchedApplications].
  2. Отключите другой процесс (например, ps или top или любой другой) с помощью NSTask, прочитайте результаты и найдите себя (или передайте его через grep или что-то в этом роде).
  3. Используйте функцию GetBSDProcessList, описанную здесь: http://developer.apple.com/legacy/mac/library/#qa/qa2001/qa1123.html (я успешно использовал это в прошлом)
3 голосов
/ 25 марта 2010

В обзоре NSRunningApplicationClass написано:

NSRunningApplication - это класс для управления и предоставления информации для одного экземпляра приложения. Отслеживаются только пользовательские приложения; это не дает информацию о каждом процессе в системе.

и

Чтобы получить доступ к списку всех запущенных приложений, используйте метод runningApplications в NSWorkspace .

Я бы предложил взглянуть на Темы программирования Workspace Services

...