简体   繁体   English

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

[英]Retrieve names of running processes

First off, I know that similar questions have been asked, but the answers provided haven't been very helpful so far (they all recommend one of the following options). 首先,我知道有人问过类似的问题,但是到目前为止,所提供的答案并不是很有帮助(他们都建议使用以下选项之一)。

I have a user application that needs to determine if a particular process is running. 我有一个用户应用程序,需要确定特定进程是否正在运行。 Here's what I know about the process: 这是我对流程的了解:

  • The name 名字
  • The user ( root ) 用户( root
  • It should already be running, since it's a LaunchDaemon, which means 应该已经在运行,因为它是LaunchDaemon,这意味着
  • Its parent process should be launchd (pid 1) 它的父进程应该launchd (pid 1)

I've tried several ways to get this, but none have worked so far. 我已经尝试了几种方法来实现此目的,但是到目前为止,没有一种方法起作用。 Here's what I've tried: 这是我尝试过的:

  1. Running ps and parsing the output. 运行ps并解析输出。 This works, but it's slow ( fork / exec is expensive), and I'd like this to be as fast as possible. 这行得通,但是很慢( fork / exec很昂贵),我希望它尽可能快。

  2. Using the GetBSDProcessList function listed here . 使用此处列出GetBSDProcessList函数。 This also works, but the way in which they say to retrieve the process name (accessing kp_proc.p_comm from each kinfo_proc structure) is flawed. 这也kp_proc.p_comm ,但是他们说检索进程名称(从每个kinfo_proc结构访问kp_proc.p_comm )的方式存在缺陷。 The resulting char* only contains the first 16 characters of the process name, which can be seen in the definition of the kp_proc structure: 结果char*仅包含进程名称的前16个字符,可以在kp_proc结构的定义中看到:

     #define MAXCOMLEN 16 //defined in param.h #define MAXCOMLEN 16 //在param.h中定义\nstruct extern_proc { //defined in proc.h struct extern_proc {//在proc.h中定义\n  ...snip... ...剪...\n  char p_comm[MAXCOMLEN+1]; 字符p_comm [MAXCOMLEN + 1];\n  ...snip... ...剪...\n}; }; 
  3. Using libProc.h to retrieve process information: 使用libProc.h检索进程信息:

     pid_t pids[1024]; pid_t pids [1024];\nint numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0); int numberOfProcesses = proc_listpids(PROC_ALL_PIDS,0,NULL,0);   \nproc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids)); proc_listpids(PROC_ALL_PIDS,0,pids,sizeof(pids));    \nfor (int i = 0; i < numberOfProcesses; ++i) { for(int i = 0; i <numberOfProcesses; ++ i){\n  if (pids[i] == 0) { continue; 如果(pids [i] == 0){继续; } }\n  char name[1024]; 字符名称[1024];\n  proc_name(pids[i], name, sizeof(name)); proc_name(pids [i],名称,sizeof(名称));\n  printf("Found process: %s\\n", name); printf(“找到进程:%s \\ n”,名称);\n} } 

    This works, except it has the same flaw as GetBSDProcessList . 除了具有与GetBSDProcessList相同的缺陷外,此方法有效。 Only the first portion of the process name is returned. 仅返回过程名称的第一部分。

  4. Using the ProcessManager function in Carbon: 在Carbon中使用ProcessManager函数

     ProcessSerialNumber psn; ProcessSerialNumber psn;\npsn.lowLongOfPSN = kNoProcess; psn.lowLongOfPSN = kNoProcess;\npsn.highLongOfPSN = 0; psn.highLongOfPSN = 0;\nwhile (GetNextProcess(&psn) == noErr) { 而(GetNextProcess(&psn)== noErr){\n  CFStringRef procName = NULL; CFStringRef procName = NULL;\n  if (CopyProcessName(&psn, &procName) == noErr) { 如果(CopyProcessName(&psn,&procName)== noErr){\n    NSLog(@"Found process: %@", (NSString *)procName); NSLog(@“找到进程:%@”,(NSString *)procName);\n  } }\n  CFRelease(procName); CFRelease(procName);\n} } 

    This does not work. 这是行不通的。 It only returns process that are registered with the WindowServer (or something like that). 它仅返回已在WindowServer中注册的进程(或类似的东西)。 In other words, it only returns apps with UIs, and only for the current user. 换句话说,它仅返回具有UI的应用程序,并且仅针对当前用户。

  5. I can't use -[NSWorkspace launchedApplications] , since this must be 10.5-compatible. 我不能使用-[NSWorkspace launchedApplications] ,因为它必须与10.5兼容。 In addition, this only returns information about applications that appear in the Dock for the current user. 此外,这仅返回有关当前用户在Dock中显示的应用程序的信息。

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 ?". 我知道可以检索正在运行的进程的名称(因为ps可以做到),但问题是“我可以不派生和执行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 . 我发现了这个问题 ,它在python模块中引用了这个C文件 This was really useful in trying to use the KERN_PROCARGS values in a sysctl call. 这对于尝试在sysctl调用中使用KERN_PROCARGS值非常有用。

However, Python module code seemed to be derived from the source to ps , which I found here . 但是,Python模块代码似乎源于ps我在这里找到了 ps can somehow get the executable path of every running process, but my best efforts to extract how its doing this have been unsuccessful. ps能以某种方式让每一个正在运行的进程的可执行文件路径,但以提取其如何做这个都没有成功我最大的努力。 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. print.c有一个名为getproclline的函数似乎在发挥作用,但是当我从自己的命令行工具中运行相同的代码时,我无法检索除我自己以外的任何进程的可执行程序。

I'll keep experimenting, but without more conclusive evidence, it looks like @drawnonward's answer is the most correct so far. 我将继续进行实验,但是在没有更多确凿证据的情况下,看来@drawnonward的答案是迄今为止最正确的答案。


EDIT (a long time later) 编辑(很久以后)

Thanks to the answer pointed to by Quinn Taylor , I've found something that works. 感谢Quinn Taylor指出的答案,我发现了一些可行的方法。 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);
    }
}

What about this answer to a related question? 这个相关问题的答案呢? https://stackoverflow.com/a/12274588/120292 This purports to get the full path for a process by the pid, and you can grab just the last path component. https://stackoverflow.com/a/12274588/120292这旨在通过pid获取进程的完整路径,并且您可以仅获取最后一个路径组件。

The only complete list of running processes is provided by 2 above, asking the kernel. 上面的2向内核询问,提供了正在运行的进程的唯一完整列表。 Getting the actual name of the process is not straight forward. 获取进程的实际名称并非直截了当。 In a nutshell, you look up the pid in any other source you can find until you get a match. 简而言之,您将在可以找到的任何其他源中查找pid,直到找到匹配项。

For some processes, the following will work: 对于某些过程,以下将起作用:

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

For some processes, you can look up the pid in the results of [[NSWorkspace sharedWorkspace] launchedApplications] by NSApplicationProcessIdentifier . 对于某些进程,您可以在NSApplicationProcessIdentifier[[NSWorkspace sharedWorkspace] launchedApplications]结果中查找pid。 Available with 10.2 and later. 在10.2和更高版本中可用。 Most, but maybe not all, items in this list will be the same as CopyProcessName above. 此列表中的大多数(但不是全部)项目将与上面的CopyProcessName相同。

For some processes, you can look up the process arguments and get the full path from the first argument. 对于某些流程,您可以查找流程参数并从第一个参数获取完整路径。 Similar to getting the original list, but using KERN_PROCARGS or KERN_PROCARGS2 as the second mib value. 与获取原始列表相似,但使用KERN_PROCARGS或KERN_PROCARGS2作为第二个mib值。 This is what ps is doing. 这就是ps在做什么。

For some processes, you are stuck with the 16 character p_comm. 对于某些进程,您只能使用16个字符的p_comm。

Not sure if this is what you're looking for, but could you use the LaunchServices API with __ LSCopyApplicationArrayInFrontToBackOrder ? 不知道这是否是您要查找的内容,但是可以将LaunchServices API与LSCopyApplicationArrayInFrontToBackOrder吗? I've heard of this, but never used it myself. 我听说过,但我自己从未使用过。 After some googling, here's a code sample that might provide what you're looking for? 经过一番谷歌搜索后,下面的代码示例可能会提供您想要的内容? I really don't know and am guessing a little ;) 我真的不知道,我猜了一点;)

http://gist.github.com/163918 http://gist.github.com/163918

Edit 编辑

Actually, Ha. 原来是哈 Here's a Stack Overflow post that gives this as an answer and links to the same post I linked to... 这是一个Stack Overflow帖子,它给出了答案并链接到我链接到的同一帖子...

http://www.stackoverflow.com/questions/945033/getting-the-list-of-running-applications-ordered-by-last-use 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