我有一个用户应用程序需要确定特定进程是否正在运行。以下是我对该过程的了解:
>名字
>用户(root)
它应该已经在运行,因为它是一个LaunchDaemon,这意味着
>其父进程应该是launchd(pid 1)
我已经尝试了几种方法来获得这个,但是迄今为止还没有一个工作。这里是我试过:
>运行ps并解析输出。这是有效的,但速度很慢(fork / exec很贵),我希望这样尽可能快。
>使用GetBSDProcessList函数listed here.这也是有效的,但是他们说的方式来检索进程名称(从每个kinfo_proc结构访问kp_proc.p_comm)是有缺陷的。所得到的char *仅包含进程名称的前16个字符,可以在kp_proc结构的定义中看到:
#define MAXCOMLEN 16 //defined in param.h struct extern_proc { //defined in proc.h ...snip... char p_comm[MAXCOMLEN+1]; ...snip... };
>使用libProc.h检索过程信息:
pid_t pids[1024]; int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0); proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids)); for (int i = 0; i < numberOfProcesses; ++i) { if (pids[i] == 0) { continue; } char name[1024]; proc_name(pids[i], name, sizeof(name)); printf("Found process: %s\n", name); }
这有效,除了它与GetBSDProcessList有相同的缺陷。只返回进程名称的第一部分。
>使用ProcessManager function碳:
ProcessSerialNumber psn; psn.lowLongOfPSN = kNoProcess; psn.highLongOfPSN = 0; while (GetNextProcess(&psn) == noErr) { CFStringRef procName = NULL; if (CopyProcessName(&psn, &procName) == noErr) { NSLog(@"Found process: %@", (NSString *)procName); } CFRelease(procName); }
这不工作。它只返回在WindowServer中注册的进程(或类似的东西)。换句话说,它只返回具有UI的应用程序,并且仅为当前用户返回。
>我不能使用-[NSWorkspace launchedApplications]
,因为这必须是10.5兼容。此外,这仅返回有关当前用户的Dock中出现的应用程序的信息。
我知道可以检索正在运行的进程的名称(因为ps可以做到这一点),但是问题是“我可以在没有分支和执行ps的情况下执行它”。
有什么建议么?
编辑
在做了更多的研究之后,我一直找不到这样做的方法。我发现this SO question,其中提到了this C file in a python module.这在尝试在sysctl调用中使用KERN_PROCARGS值非常有用。
然而,Python模块代码似乎是从源代码派生到ps,which I found here. ps可以以某种方式获取每个正在运行的进程的可执行路径,但是我尽最大的努力来提取它的做法是不成功的。在print.c中有一个函数,称为getproclline,似乎在做魔术,但是当我从自己的命令行工具中运行相同的代码时,我无法检索除自己以外的任何进程的进程可执行文件。
我会继续尝试,但没有更多的确凿证据,看起来@ drawonward的答案是最为正确的。
编辑(很久以后)
感谢答案pointed to by Quinn Taylor,我发现了一些有用的东西。它获取每个进程的可执行路径,然后我可以抓住最后一个路径组件来获取实际的进程名称。
#import <sys/proc_info.h> #import <libproc.h> int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0); pid_t pids[numberOfProcesses]; bzero(pids, sizeof(pids)); proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids)); for (int i = 0; i < numberOfProcesses; ++i) { if (pids[i] == 0) { continue; } char pathBuffer[PROC_PIDPATHINFO_MAXSIZE]; bzero(pathBuffer, PROC_PIDPATHINFO_MAXSIZE); proc_pidpath(pids[i], pathBuffer, sizeof(pathBuffer)); if (strlen(pathBuffer) > 0) { printf("path: %s\n", pathBuffer); } }相关问题的答案如何? http://stackoverflow.com/a/12274588/120292这个目的是通过pid获得一个进程的完整路径,你可以抓住最后一个路径组件。