Dav*_*ong 30 c macos process objective-c
首先,我知道已经提出过类似的问题,但到目前为止提供的答案并不是很有用(他们都建议使用以下选项之一).
我有一个用户应用程序需要确定特定进程是否正在运行.以下是我对该过程的了解:
root)launchd(pid 1)我已经尝试了几种方法来实现这一点,但到目前为止还没有任何方法.这是我尝试过的:
运行ps并解析输出.这有效,但速度很慢(fork/ exec很贵),我希望尽可能快.
使用此处列出的GetBSDProcessList功能.这也有效,但他们说检索进程名称(从每个结构访问)的方式是有缺陷的.结果只包含进程名称的前16个字符,可以在结构的定义中看到:kp_proc.p_commkinfo_procchar*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.仅返回进程名称的第一部分.
在Carbon中使用ProcessManager函数:
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吗?".
有什么建议?
编辑
经过更多的研究后,我一直无法找到办法.我发现了这个问题,它在python模块中引用了这个C文件.这在尝试使用调用中的KERN_PROCARGS值时非常有用sysctl.
但是,Python模块代码似乎是从源代码派生的ps,我在这里找到了. ps能以某种方式让每一个正在运行的进程的可执行文件路径,但提取我最大的努力如何它这样做不成功.在print.c被调用getproclline中有一个似乎正在做魔术的函数,但是当我从我自己的命令行工具中运行相同的代码时,我无法检索除我自己以外的任何进程的进程可执行文件.
我会继续尝试,但没有更确凿的证据,看起来@drawonward的答案到目前为止是最正确的.
编辑(很久以后)
感谢奎因泰勒指出的答案,我发现了一些有效的东西.它获取每个进程的可执行路径,然后我可以抓住最后一个路径组件来获取实际的进程名称.
#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);
}
}
Run Code Online (Sandbox Code Playgroud)