代码之家  ›  专栏  ›  技术社区  ›  Dave DeLong

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

  •  28
  • Dave DeLong  · 技术社区  · 15 年前

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

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

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

    我试过几种方法来达到这个目的,但到目前为止都没有奏效。以下是我的尝试:

    1. 运行 ps 分析输出。这行,但很慢( fork / exec 很贵),我希望这个尽快。

    2. 使用 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...
      };
    3. 使用 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);
      }

      这是可行的,除了它有同样的缺陷 获取BSDProcessList . 只返回进程名称的第一部分。

    4. 使用 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);
      }

      这不起作用。它只返回在WindowsServer中注册的进程(或类似的进程)。换句话说,它只返回带有uis的应用程序,并且只返回当前用户。

    5. 我不能用 -[NSWorkspace launchedApplications] ,因为这必须是10.5兼容的。此外,这只返回有关当前用户在Dock中显示的应用程序的信息。

    我知道这是 可能的 检索正在运行的进程的名称(自 聚苯乙烯 但问题是“我能做到不分岔吗?” 聚苯乙烯 “.

    有什么建议吗?

    编辑

    在做了很多研究之后,我一直找不到一种方法来做这件事。我发现 this SO question ,其中提到 this C file in a python module . 这在尝试使用 KERN_PROCARGS A中的值 sysctl 打电话。

    然而,python模块代码似乎是从源代码派生到 聚苯乙烯 , which I found here . 聚苯乙烯 可以以某种方式获取每个正在运行的进程的可执行路径,但我尽最大努力提取 怎样 这样做是不成功的。有一个函数在 print.c 打电话 getproclline 这看起来很神奇,但是当我在自己的命令行工具中运行相同的代码时,除了自己的进程之外,我无法检索其他进程的进程可执行文件。

    我会继续试验,但如果没有更确凿的证据,看起来@drawnonward的答案是目前为止最正确的。


    编辑(很久以后)

    谢谢你的回答 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);
        }
    }
    
    3 回复  |  直到 9 年前
        1
  •  8
  •   Community CDub    8 年前

    关于一个相关问题的答案呢? https://stackoverflow.com/a/12274588/120292 这意味着通过pid获得进程的完整路径,您可以只获取最后一个路径组件。

        2
  •  2
  •   drawnonward    15 年前

    上面的2提供了运行进程的唯一完整列表,询问内核。获取进程的实际名称并不是直接的。简而言之,在找到匹配项之前,您可以在任何其他源中查找PID。

    对于某些流程,以下内容将起作用:

    ProcessSerialNumber         psn;
    CFStringRef             name = NULL;
    status = GetProcessForPID( inPID , &psn );
    if ( noErr == status ) CopyProcessName( &psn , &name );
    

    对于某些进程,可以在 [[NSWorkspace sharedWorkspace] launchedApplications] 通过 NSApplicationProcessIdentifier . 10.2及更高版本。此列表中的大多数(但可能不是全部)项将与上面的CopyProcessName相同。

    对于某些进程,可以查找进程参数并从第一个参数获取完整路径。类似于获取原始列表,但使用kern_procargs或kern_procargs2作为第二个mib值。这是什么 ps 正在做。

    对于某些进程,您只能使用16个字符的p_命令。

        3
  •  0
  •   lewiguez    15 年前

    不知道这是不是你要找的,但是你能用一下吗 LaunchServices 带API的API LSCopyApplicationArrayInFrontToBackOrder ?我听说过这个,但我自己从来没有用过。在谷歌搜索之后,这里有一个代码示例,可以提供您要查找的内容?我真的不知道,只是有点猜测;)

    http://gist.github.com/163918

    编辑

    事实上,哈。这里有一个栈溢出帖子,它给出了一个答案,并链接到我链接到的同一个帖子…

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