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

标签 c objective-c macos process

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

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

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

我已经尝试了几种方法来获得它,但到目前为止都没有奏效。这是我尝试过的:

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

  2. 使用 GetBSDProcessList 函数 listed here .这也有效,但他们所说的检索进程名称的方式(从每个 kinfo_proc 结构访问 kp_proc.p_comm)是有缺陷的。得到的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. Using libProc.h to retrieve process information:

    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);
    }

    This works, except it has the same flaw as GetBSDProcessList. Only the first portion of the process name is returned.

  4. Using the ProcessManager function in Carbon:

    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);
    }

    This does not work. It only returns process that are registered with the WindowServer (or something like that). In other words, it only returns apps with UIs, and only for the current user.

  5. I can't use -[NSWorkspace launchedApplications], since this must be 10.5-compatible. In addition, this only returns information about applications that appear in the Dock for the current user.

I know that it's possible to retrieve the name of running processes (since ps can do it), but the question is "Can I do it without forking and exec'ing ps?".

Any suggestions?

EDIT

After doing a lot more research, I've been unable to find a way to do this. I found this SO question, which referred to this C file in a python module. This was really useful in trying to use the KERN_PROCARGS values in a sysctl call.

However, Python module code seemed to be derived from the source to ps, which I found here. ps can somehow get the executable path of every running process, but my best efforts to extract how its doing this have been unsuccessful. There's a function in print.c called getproclline that seems to be doing the magic, but when I run the same code from within my own command line tool, I'm unable to retrieve the process executable for any processes other than my own.

I'll keep experimenting, but without more conclusive evidence, it looks like @drawnonward's answer is the most correct so far.


EDIT (a long time later)

Thanks to the answer pointed to by Quinn Taylor, I've found something that works. It gets the executable path of each process, and then I can just grab the last path component to get the actual process name.

#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 获取进程的完整路径,您可以只获取最后一个路径组件。

关于c - 检索正在运行的进程的名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3018054/

相关文章:

c - 在什么条件下管道读取是原子的?

c - Sparc 过程调用约定

c - libcURL CURLOPT_SSLKEYTYPE

c - 为什么我的机器在此代码中将堆栈指针减少 20?

objective-c - 如何拥有不同的 NSManagedObjectContext?

ios - 用于 webView 的 scalesPageToFit 不适用于 iOS 9.3

ios - 来自 foursquare 的图像是 NSURLErrorFileDoesNotExist = -1100

c++ - 可以从 C++ DLL 项目创建 DYLIB 吗?

ruby-on-rails - 从目录打开Vim时如何自动返回 'set path'?

java - Mac OS X Java 更新的源代码