我想知道是否可以确定哪个进程负责在 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为了这:
- 启动 Automator(在聚光灯下输入
Automator.app
+ Enter) - 创建新的工作流程。
- 在菜单上选择工作流>记录(或点击