首先,我知道已经提出了类似的问题,但到目前为止提供的答案并不是很有用(他们都建议使用以下选项之一)。
我有一个用户应用程序需要确定特定进程是否正在运行。以下是我对该过程的了解:
root
)launchd
(pid 1)我已经尝试了几种方法来实现这一点,但到目前为止还没有任何方法可行。这是我尝试过的:
运行ps
并解析输出。这很有效,但速度很慢(fork
/ exec
很贵),我希望这一点尽可能快。
使用GetBSDProcessList
函数listed here。这也有效,但他们说检索进程名称(从每个kp_proc.p_comm
结构访问kinfo_proc
)的方式是有缺陷的。结果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
具有相同的缺陷。仅返回流程名称的第一部分。
在Carbon中使用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
可以这样做),但问题是“我能不执行而不执行{exec'ing { {1}}?”。
有什么建议吗?
修改
经过更多的研究后,我一直无法找到办法。我找到了this SO question,其中提到了this C file in a python module。这对于尝试在ps
调用中使用KERN_PROCARGS
值非常有用。
但是,Python模块代码似乎源自sysctl
,which I found here。 ps
可以某种方式获取每个正在运行的进程的可执行路径,但我尽最大努力提取如何执行此操作是不成功的。 ps
中有一个名为print.c
的函数似乎正在发挥作用,但是当我从我自己的命令行工具中运行相同的代码时,我无法检索任何进程的进程可执行文件不是我自己的。
我会继续尝试,但如果没有更确凿的证据,看起来@drawonward的答案到目前为止是最正确的。
编辑(很久以后)
感谢答案pointed to by Quinn Taylor,我找到了有效的方法。它获取每个进程的可执行路径,然后我可以抓住最后一个路径组件来获取实际的进程名称。
getproclline
答案 0 :(得分:8)
相关问题的答案怎么样? https://stackoverflow.com/a/12274588/120292这声称可以通过pid获取进程的完整路径,并且您可以只获取最后一个路径组件。
答案 1 :(得分:2)
上面2中提供了运行进程的唯一完整列表,询问内核。获取流程的实际名称并不是直截了当的。简而言之,您可以在找到匹配项之前查找任何其他来源的pid。
对于某些流程,以下内容将起作用:
ProcessSerialNumber psn;
CFStringRef name = NULL;
status = GetProcessForPID( inPID , &psn );
if ( noErr == status ) CopyProcessName( &psn , &name );
对于某些流程,您可以在[[NSWorkspace sharedWorkspace] launchedApplications]
NSApplicationProcessIdentifier
的结果中查找pid。适用于10.2及更高版本。此列表中的大多数(但可能不是全部)项目与上面的CopyProcessName相同。
对于某些进程,您可以查找进程参数并从第一个参数获取完整路径。与获取原始列表类似,但使用KERN_PROCARGS或KERN_PROCARGS2作为第二个mib值。这就是ps
正在做的事情。
对于某些进程,您会遇到16个字符的p_comm。
答案 2 :(得分:0)
不确定这是否是您要找的,但是您可以将LaunchServices
API与__ LSCopyApplicationArrayInFrontToBackOrder
一起使用吗?我听说过这个,但从来没有用过它。经过一些谷歌搜索,这里有一个代码示例可能提供您正在寻找的东西?我真的不知道,我猜一点;)
<强> 修改 强>
实际上,哈。这是一个Stack Overflow帖子,它将此作为答案并链接到我链接到的相同帖子...