繁体   English   中英

检索正在运行的进程的名称

[英]Retrieve names of running processes

首先,我知道有人问过类似的问题,但是到目前为止,所提供的答案并不是很有帮助(他们都建议使用以下选项之一)。

我有一个用户应用程序,需要确定特定进程是否正在运行。 这是我对流程的了解:

  • 名字
  • 用户( root
  • 应该已经在运行,因为它是LaunchDaemon,这意味着
  • 它的父进程应该launchd (pid 1)

我已经尝试了几种方法来实现此目的,但是到目前为止,没有一种方法起作用。 这是我尝试过的:

  1. 运行ps并解析输出。 这行得通,但是很慢( fork / exec很昂贵),我希望它尽可能快。

  2. 使用此处列出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 }; 
  3. 使用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相同的缺陷外,此方法有效。 仅返回过程名称的第一部分。

  4. 在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的应用程序,并且仅针对当前用户。

  5. 我不能使用-[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吗? 我听说过,但我自己从未使用过。 经过一番谷歌搜索后,下面的代码示例可能会提供您想要的内容? 我真的不知道,我猜了一点;)

http://gist.github.com/163918

编辑

原来是哈 这是一个Stack Overflow帖子,它给出了答案并链接到我链接到的同一帖子...

http://www.stackoverflow.com/questions/945033/getting-the-list-of-running-applications-ordered-by-last-use

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM