如何识别 Mac OS X 中哪个进程正在运行哪个窗口?

如何识别 Mac OS X 中哪个进程正在运行哪个窗口?

我想知道是否可以确定哪个进程负责在 Mac OS X 中创建/管理窗口。

例如,当启动应用程序的多个实例时,如何获取某个特定窗口对应的进程 ID (PID)?或者,如果有一个没有标题的模态对话框窗口,如何获取其所有者的 PID?

我知道在 Windows 中可以使用Sysinternals 套件该工具提供了一种搜索正在运行的一些数据的库的方法。

我正在寻找一种类似于这篇博文

在这种情况下,使用 Sysinternals Suite(和 Process Explorer),他们通过搜索 DLL 或子字符串(在本例中,使用设备的物理名称)来找到哪个 DLL/程序正在使用网络摄像头。

那么是否存在任何机制或程序,或者您是否知道如何在 Mac OS X 中搜索类似的东西?我如何确定哪个进程启动了窗口?

答案1

我用过这个 Python 2 脚本。它不是万无一失的,但对我来说效果很好。

以下是它的功能摘要:它使用CGWindowListCopyWindowInfo从 导入的 来Quartz从系统收集窗口信息,然后要求用户移动所需窗口,然后再次收集窗口信息,并显示已更改窗口的信息。转储的信息包括进程 ID,如kCGWindowOwnerPID

以下是代码:

#!/usr/bin/env python

import time
from Quartz import CGWindowListCopyWindowInfo, kCGWindowListExcludeDesktopElements, kCGNullWindowID
from Foundation import NSSet, NSMutableSet

wl1 = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID)
print 'Move target window'
time.sleep(5)
wl2 = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID)

w = NSMutableSet.setWithArray_(wl1)
w.minusSet_(NSSet.setWithArray_(wl2))
print '\nList of windows that moved:'
print w
print '\n'

该脚本打印在 5 秒间隔内改变位置的窗口的信息。因此输出如下所示:

List of windows that moved:
{(
        {
        kCGWindowAlpha = 1;
        kCGWindowBounds =         {
            Height = 217;
            Width = 420;
            X = 828;
            Y = 213;
        };
        kCGWindowIsOnscreen = 1;
        kCGWindowLayer = 8;
        kCGWindowMemoryUsage = 406420;
        kCGWindowName = "";
        kCGWindowNumber = 77;
        kCGWindowOwnerName = UserNotificationCenter;
        kCGWindowOwnerPID = 481;
        kCGWindowSharingState = 1;
        kCGWindowStoreType = 2;
    }
)}

答案2

我制作了一个名为lswin

#!/usr/bin/env python

# Install Quartz with 'pip install -U pyobjc-framework-Quartz'
import Quartz

#wl = Quartz.CGWindowListCopyWindowInfo( Quartz.kCGWindowListOptionOnScreenOnly | Quartz.kCGWindowListExcludeDesktopElements, Quartz.kCGNullWindowID)
wl = Quartz.CGWindowListCopyWindowInfo( Quartz.kCGWindowListOptionAll, Quartz.kCGNullWindowID)

wl = sorted(wl, key=lambda k: k.valueForKey_('kCGWindowOwnerPID'))

#print wl

print('PID'.rjust(7) + ' ' + 'WinID'.rjust(5) + '  ' + 'x,y,w,h'.ljust(21) + ' ' + '\t[Title] SubTitle')
print('-'.rjust(7,'-') + ' ' + '-'.rjust(5,'-') + '  ' + '-'.ljust(21,'-') + ' ' + '\t-------------------------------------------')

for v in wl:
    raw_chars = ( \
        str(v.valueForKey_('kCGWindowOwnerPID') or '?').rjust(7) + \
        ' ' + str(v.valueForKey_('kCGWindowNumber') or '?').rjust(5) + \
        ' {' + ('' if v.valueForKey_('kCGWindowBounds') is None else \
            ( \
                str(int(v.valueForKey_('kCGWindowBounds').valueForKey_('X')))     + ',' + \
                str(int(v.valueForKey_('kCGWindowBounds').valueForKey_('Y')))     + ',' + \
                str(int(v.valueForKey_('kCGWindowBounds').valueForKey_('Width'))) + ',' + \
                str(int(v.valueForKey_('kCGWindowBounds').valueForKey_('Height'))) \
            ) \
            ).ljust(21) + \
        '}' + \
        '\t[' + ((v.valueForKey_('kCGWindowOwnerName') or '') + ']') + \
        ('' if v.valueForKey_('kCGWindowName') is None else (' ' + v.valueForKey_('kCGWindowName') or '')) \
    )
    print(raw_chars)

答案3

有一个直接的用户友好的操作系统原生工具用于检查每个窗口,除了相关过程之外,它还提供全面的信息,例如原始代码层次结构:它位于 Xcode 开发人员工具下,称为Accessibility Inspector

答案4

您可以使用Automator.app为了这:

  1. 启动 Automator(在聚光灯下输入Automator.app+ Enter
  2. 创建新的工作流程。
  3. 在菜单上选择工作流>记录(或点击

相关内容