我如何从一个进程获取信息,它是UI(用户界面)进程还是非用户进程?
对于UI进程,我的意思是,Finder,Dock,系统UI服务器,或任何其他具有UI界面的Mac应用程序,它被Window Server使用。
我想从ProcessID中确定这个信息。
我正在使用mac os x。
没有办法纯粹根据PID 号确定具体的过程是什么。 原因如下:进程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 ...
编辑:你可能能够做你所问,虽然它是错综复杂的。 这个答案提到:
CGWindow.h中的函数CGWindowListCopyWindowInfo()将返回一个字典数组,每个窗口与您设置的条件匹配,包括其他应用程序中的条件。 它只允许您通过给定窗口上的窗口,给定窗口和“屏幕上”窗口下的窗口进行过滤,但是返回的字典包含拥有应用程序的进程ID,您可以使用该进程ID来匹配窗口到应用程序。
如果你可以获得所有的CGWindow
和它们各自的pid
,那么你就可以知道所有UI应用程序的pid
,而不需要运行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; }
尝试以下。
#include <unistd.h> if (isatty(STDIN_FILENO) || isatty(STDOUT_FILENO) || isatty(STDERR_FILENO)) // Process associated with a terminal else // No terminal - probably UI process
在darvids的行上,下面是你的问题的答案。
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; }
只要比较你对数组项目的processid就可以得到想要的结果。