且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何识别用户界面进程中的进程?

更新时间:2023-12-01 17:50:22

无法仅基于PID 数字来确定特定过程是什么.这样做的原因是:在启动时从PID = 1顺序分配(某种程度上)进程ID,并且对于不同的系统启动可能会有所不同.例如,如果Finder或Dock崩溃并且必须重新启动,则还将重新分配进程ID.

There is no way to determine based purely on the PID number what a specific process is. The reason for this: Process IDs are assigned (somewhat) sequentially from PID=1 on startup, and startup can be different for different systems. The process ID will also be reassigned if, for example, Finder or Dock crashes and has to be restarted.

但是,如果可以使用特定的pid运行终端命令,请执行以下操作:

If you can run a terminal command with a specific pid that you have, though, do this:

ps -p <pid> -o ucomm=

您将获得该进程的文件名,您可以根据您知道的UI进程列表来进行检查.例如,这是我系统上当前登录会话的某些ps命令的输出:

You'll get the filename of the process, which you can check against a list of ones you know are UI processes. For example, here is the output of certain ps commands on my system for my current login session:

> ps -p 110 -o ucomm=
Dock

> ps -p 112 -o ucomm=
Finder

以下命令将按进程ID的顺序提供进程列表,仅包含名称:

And the following command will give you a list of processes in order of process ID, with only the name:

> ps -ax -o pid=,ucomm=
   1 launchd
  10 kextd
  11 DirectoryService
     ...


尽管令人费解,但您仍然可以按照自己的要求做. 答案提到:


You may be able to do what you ask, though it is convoluted. This answer mentions:

来自CGWindow.h的函数CGWindowListCopyWindowInfo()将返回一个字典数组,每个与您设置的条件匹配的窗口(包括其他应用程序中的一个)都将包含一个字典.它仅允许您按给定窗口上方的窗口,给定窗口下方的窗口和屏幕上"窗口进行过滤,但是返回的字典包含拥有应用程序的进程ID,可用于将窗口与应用程序进行匹配.

The function CGWindowListCopyWindowInfo() from CGWindow.h will return an array of dictionaries, one for each window that matches the criteria you set, including ones in other applications. It only lets you filter by windows above a given window, windows below a given window and 'onscreen' windows, but the dictionary returned includes a process ID for the owning app which you can use to match up window to app.

如果可以获得所有CGWindow和它们各自的pid,那么您将知道所有UI应用程序的pid,而无需完全运行ps.

If you can obtain all the CGWindows and their respective pids, then you will know the pids of all UI applications without needing to run ps at all.

Rahul为此方法实现了以下代码,他要求我将其添加到我的答案中:

Rahul has implemented the following code for this approach, which he requested I add to my answer:

CFArrayRef UiProcesses()
{
    CFArrayRef  orderedwindows = CGWindowListCopyWindowInfo(kCGWindowListOptionAll, kCGNullWindowID);
    CFIndex count = CFArrayGetCount (orderedwindows);
    CFMutableArrayRef uiProcess = CFArrayCreateMutable (kCFAllocatorDefault , count,  &kCFTypeArrayCallBacks);
    for (CFIndex i = 0; i < count; i++)
    {
        if (orderedwindows)
        {
            CFDictionaryRef windowsdescription = (CFDictionaryRef)CFArrayGetValueAtIndex(orderedwindows, i);
            CFNumberRef windowownerpid  = (CFNumberRef)CFDictionaryGetValue (windowsdescription, CFSTR("kCGWindowOwnerPID"));
            CFArrayAppendValue (uiProcess, windowownerpid);

        }
    }
    return uiProcess;
}