[英]Retrieve names of running processes
首先,我知道有人问过类似的问题,但是到目前为止,所提供的答案并不是很有帮助(他们都建议使用以下选项之一)。
我有一个用户应用程序,需要确定特定进程是否正在运行。 这是我对流程的了解:
root
) launchd
(pid 1) 我已经尝试了几种方法来实现此目的,但是到目前为止,没有一种方法起作用。 这是我尝试过的:
运行ps
并解析输出。 这行得通,但是很慢( fork
/ exec
很昂贵),我希望它尽可能快。
使用此处列出的GetBSDProcessList
函数。 这也kp_proc.p_comm
,但是他们说检索进程名称(从每个kinfo_proc
结构访问kp_proc.p_comm
)的方式存在缺陷。 结果char*
仅包含进程名称的前16个字符,可以在kp_proc
结构的定义中看到:
#define MAXCOMLEN 16 //在param.h中定义\n struct extern_proc {//在proc.h中定义\n ...剪...\n 字符p_comm [MAXCOMLEN + 1];\n ...剪...\n };
使用libProc.h检索进程信息:
pid_t pids [1024];\n int numberOfProcesses = proc_listpids(PROC_ALL_PIDS,0,NULL,0); \n proc_listpids(PROC_ALL_PIDS,0,pids,sizeof(pids)); \n for(int i = 0; i <numberOfProcesses; ++ i){\n 如果(pids [i] == 0){继续; }\n 字符名称[1024];\n proc_name(pids [i],名称,sizeof(名称));\n printf(“找到进程:%s \\ n”,名称);\n }
除了具有与GetBSDProcessList
相同的缺陷外,此方法有效。 仅返回过程名称的第一部分。
在Carbon中使用ProcessManager函数 :
ProcessSerialNumber psn;\n psn.lowLongOfPSN = kNoProcess;\n psn.highLongOfPSN = 0;\n 而(GetNextProcess(&psn)== noErr){\n CFStringRef procName = NULL;\n 如果(CopyProcessName(&psn,&procName)== noErr){\n NSLog(@“找到进程:%@”,(NSString *)procName);\n }\n CFRelease(procName);\n }
这是行不通的。 它仅返回已在WindowServer中注册的进程(或类似的东西)。 换句话说,它仅返回具有UI的应用程序,并且仅针对当前用户。
我不能使用-[NSWorkspace launchedApplications]
,因为它必须与10.5兼容。 此外,这仅返回有关当前用户在Dock中显示的应用程序的信息。
我知道可以检索正在运行的进程的名称(因为ps
可以做到),但问题是“我可以不派生和执行ps
吗?”。
有什么建议么?
编辑
经过大量研究后,我一直无法找到一种方法。 我发现了这个问题 ,它在python模块中引用了这个C文件 。 这对于尝试在sysctl
调用中使用KERN_PROCARGS
值非常有用。
但是,Python模块代码似乎源于ps
, 我在这里找到了 。 ps
能以某种方式让每一个正在运行的进程的可执行文件路径,但以提取其如何做这个都没有成功我最大的努力。 在print.c
有一个名为getproclline
的函数似乎在发挥作用,但是当我从自己的命令行工具中运行相同的代码时,我无法检索除我自己以外的任何进程的可执行程序。
我将继续进行实验,但是在没有更多确凿证据的情况下,看来@drawnonward的答案是迄今为止最正确的答案。
编辑(很久以后)
感谢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);
}
}
这个相关问题的答案呢? https://stackoverflow.com/a/12274588/120292这旨在通过pid获取进程的完整路径,并且您可以仅获取最后一个路径组件。
上面的2向内核询问,提供了正在运行的进程的唯一完整列表。 获取进程的实际名称并非直截了当。 简而言之,您将在可以找到的任何其他源中查找pid,直到找到匹配项。
对于某些过程,以下将起作用:
ProcessSerialNumber psn;
CFStringRef name = NULL;
status = GetProcessForPID( inPID , &psn );
if ( noErr == status ) CopyProcessName( &psn , &name );
对于某些进程,您可以在NSApplicationProcessIdentifier
的[[NSWorkspace sharedWorkspace] launchedApplications]
结果中查找pid。 在10.2和更高版本中可用。 此列表中的大多数(但不是全部)项目将与上面的CopyProcessName相同。
对于某些流程,您可以查找流程参数并从第一个参数获取完整路径。 与获取原始列表相似,但使用KERN_PROCARGS或KERN_PROCARGS2作为第二个mib值。 这就是ps
在做什么。
对于某些进程,您只能使用16个字符的p_comm。
不知道这是否是您要查找的内容,但是可以将LaunchServices
API与LSCopyApplicationArrayInFrontToBackOrder
吗? 我听说过,但我自己从未使用过。 经过一番谷歌搜索后,下面的代码示例可能会提供您想要的内容? 我真的不知道,我猜了一点;)
编辑
原来是哈 这是一个Stack Overflow帖子,它给出了答案并链接到我链接到的同一帖子...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.