Существует ли API-интерфейс Carbon/ Cocoa/C на Mac, который я могу использовать для перечисления процессов? Я ищу что-то вроде EnumProcesses
в Windows.
Моя цель - проверить из кода, выполняется ли процесс (по имени).
Спасибо!
Существует ли API-интерфейс Carbon/ Cocoa/C на Mac, который я могу использовать для перечисления процессов? Я ищу что-то вроде EnumProcesses
в Windows.
Моя цель - проверить из кода, выполняется ли процесс (по имени).
Спасибо!
TechZen говорит: Диспетчер процессов с декабря 2013 года полностью устарел.
А, я просто нашел Ссылка на Process Manager
Похож на GetNextProcess
и GetProcessInfo
помощь в определении того, что работает. Как предложил Дейв, GetBSDProcessList
можно использовать, если вы ищете демонов, а не только процессов Carbon/Cocoa.
Вот некоторые конкретные реализации и детали, обратите внимание, что proc- > kp_proc.p_comm имеет ограничение длины символов, поэтому я внедряю infoForPID: вместо этого
Cocoa:
[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: (см. Техническое Q & A 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;
}
Есть несколько способов сделать это:
-[NSWorkspace launchedApplications]
.NSTask
, прочитайте результаты и выполните поиск самостоятельно (или пропустите его через grep или что-то еще).GetBSDProcessList
, описанную здесь: http://developer.apple.com/legacy/mac/library/#qa/qa2001/qa1123.html (я успешно использовал это в прошлом)В обзоре NSRunningApplicationClass говорится:
NSRunningApplication - это класс для управления и предоставления информации для одного экземпляра приложения. Отслеживаются только пользовательские приложения; это не предоставляет информацию о каждом процессе в системе.
и
Чтобы получить доступ к списку всех запущенных приложений, используйте метод runningApplications в NSWorkspace.
Я бы посоветовал взглянуть на Темы программирования служб Workspace
Поздно, но если вам действительно нужно надежное решение, которое может проверить, работает ли какой-либо процесс (включая процессы BSD), вы можете сделать следующее:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/sysctl.h>
#include <sys/types.h>
int main(int argc, const char* argv[]) {
pid_t pid = atoi(argv[2]);
// This MIB array will get passed to sysctl()
// See man 3 sysctl for details
int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
struct kinfo_proc result;
size_t oldp_len = sizeof(result);
// sysctl() refuses to fill the buffer if the PID does not exist,
// so the only way to detect failure is to set all fields to 0 upfront
memset(&result, 0, sizeof(struct kinfo_proc));
if (sysctl(name, 4, &result, &oldp_len, NULL, 0) < 0) {
perror("sysctl");
return 1;
}
// SZOMB means a zombie process, one that is still visible but is not running anymore
if (result.kp_proc.p_pid > 0 && result.kp_proc.p_stat != SZOMB) {
printf("Process is running.\n");
} else {
printf("Process is NOT running.\n");
}
return 0;
}
Обратите внимание, что приведенный выше код является модифицированной версией одной из моих личных библиотек и не проверен. Тем не менее, должно быть понятно, как используется API, и он успешно работает в macOS 10.14.5.