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

Dav*_*ong 30 c macos process objective-c

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

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

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

我已经尝试了几种方法来实现这一点,但到目前为止还没有任何方法.这是我尝试过的:

  1. 运行ps并解析输出.这有效,但速度很慢(fork/ exec很贵),我希望尽可能快.

  2. 使用此处列出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...
    };
  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);
    }

    这有效,除了它有相同的缺陷GetBSDProcessList.仅返回进程名称的第一部分.

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

  5. 我不能使用-[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)

Qui*_*lor 8

对相关问题的答案怎么样?/sf/answers/859221191/这声称通过pid获取进程的完整路径,您可以只获取最后一个路径组件.