没有办法完全根据 PID number 确定特定进程是什么。原因是:进程ID在启动时从PID=1开始(有点)按顺序分配,不同系统的启动可能不同。如果 Finder 或 Dock 崩溃并且必须重新启动,也会重新分配进程 ID。
如果您可以使用您拥有的特定 pid 运行终端命令,请执行以下操作:
ps -p <pid> -o ucomm=
您将获得进程的文件名,您可以对照您知道的 UI 进程列表检查该文件名。例如,这里是我系统上某些 ps 命令的输出,用于我当前的登录会话:
> ps -p 110 -o ucomm=
Dock
> ps -p 112 -o ucomm=
Finder
下面的命令会按照进程 ID 的顺序给你一个进程列表,只有名称:
> ps -ax -o pid=,ucomm=
1 launchd
10 kextd
11 DirectoryService
...
编辑:你也许可以做你所要求的,尽管它很复杂。 This回答提到:
CGWindow.h 中的函数 CGWindowListCopyWindowInfo() 将返回一个字典数组,每个窗口对应于您设置的条件,包括其他应用程序中的条件。它只允许您按给定窗口上方的窗口、给定窗口下方的窗口和“屏幕”窗口进行过滤,但返回的字典包含所属应用程序的进程 ID,您可以使用该 ID 将窗口与应用程序匹配。
如果你能获得所有的CGWindows和它们各自的pids,那么你将知道所有UI应用程序的pids,而不需要运行ps。
Rahul 为这种方法实现了以下代码,他要求我将其添加到我的答案中:
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;
}