Nac*_*gil 41 window process macos
我想知道是否可以确定哪个进程负责在 Mac OS X 中创建/管理窗口。
例如,当启动一个应用程序的多个实例时,如何获取一个特定窗口对应的进程 ID(PID)?或者,如果有一个没有标题的模态对话框窗口,我如何获得其所有者的 PID?
我知道在 Windows 中可以使用Sysinternals Suite工具,该工具提供了一种搜索正在运行某些数据的库的方法。
我正在寻找一种类似于本博文中出现的机制。
在这种情况下,使用 Sysinternals Suite(和 Process Explorer),他们通过搜索 DLL 或子字符串(在这种情况下,使用设备的物理名称)找到了哪个 DLL/程序正在使用网络摄像头。
那么是否有任何机制或程序,或者您是否知道如何为 Mac OS X 搜索类似的东西?如何识别哪个进程启动了一个窗口?
ech*_* on 30
我用过这个 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'
Run Code Online (Sandbox Code Playgroud)
该脚本打印在 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;
}
)}
Run Code Online (Sandbox Code Playgroud)
小智 24
我做了一个名为的工具 lswin
$ python lswin.py
PID WinID x,y,w,h [Title] SubTitle
------- ----- --------------------- -------------------------------------------
169 1956 {0,-38,1280,25 } [Window Server] Backstop Menubar
169 1955 {0,-60,1280,22 } [Window Server] Menubar
169 396 {0,-38,1280,25 } [Window Server] Backstop Menubar
169 395 {0,-60,1280,22 } [Window Server] Menubar
169 6 {0,0,0,0 } [Window Server] Cursor
169 4 {0,22,1280,25 } [Window Server] Backstop Menubar
169 3 {0,0,1280,22 } [Window Server] Menubar
169 2 {0,0,1280,800 } [Window Server] Desktop
262 404 {0,-38,1280,38 } [Google Chrome]
262 393 {0,0,1280,800 } [Google Chrome]
262 380 {100,100,1,1 } [Google Chrome] Focus Proxy
... ...
Run Code Online (Sandbox Code Playgroud)
然后您可以使用 grep 来查找您的窗口的 pid。
这是脚本的源代码:
#!/usr/bin/env python
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:
print ( \
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 '')) \
).encode('utf8')
Run Code Online (Sandbox Code Playgroud)
小智 13
有一个直接用户友好的操作系统本机工具用于检查每个窗口,除了相关过程之外,它还提供全面的信息,例如原始代码层次结构:它可以在 Xcode 开发人员工具下找到,并称为Accessibility Inspector
小智 12
@kenorb 我结合了你的两个版本的脚本,基本上它像第一个版本一样工作,显示差异但格式来自第二个版本。此外,如果窗口不在屏幕上 - 它不会被打印,否则会产生太多垃圾
import Quartz
import time
from Foundation import NSSet, NSMutableSet
def transformWindowData(data):
list1 = []
for v in data:
if not v.valueForKey_('kCGWindowIsOnscreen'):
continue
row = ( \
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 '')) \
).encode('utf8')
list1.append(row)
return list1;
def printBeautifully(dataSet):
print 'PID'.rjust(7) + ' ' + 'WinID'.rjust(5) + ' ' + 'x,y,w,h'.ljust(21) + ' ' + '\t[Title] SubTitle'
print '-'.rjust(7,'-') + ' ' + '-'.rjust(5,'-') + ' ' + '-'.ljust(21,'-') + ' ' + '\t-------------------------------------------'
# print textList1
for v in dataSet:
print v;
#grab initial set
wl = Quartz.CGWindowListCopyWindowInfo( Quartz.kCGWindowListOptionAll, Quartz.kCGNullWindowID)
wl = sorted(wl, key=lambda k: k.valueForKey_('kCGWindowOwnerPID'))
#convert into readable format
textList1 = transformWindowData(wl);
#print everything we have on the screen
print 'all windows:'
printBeautifully(textList1)
print 'Move target window'
time.sleep(5)
#grab window data the second time
wl2 = Quartz.CGWindowListCopyWindowInfo(Quartz.kCGWindowListOptionAll, Quartz.kCGNullWindowID)
textList2 = transformWindowData(wl2)
#check the difference
w = NSMutableSet.setWithArray_(textList1)
w.minusSet_(NSSet.setWithArray_(textList2))
#print the difference
printBeautifully(w)
Run Code Online (Sandbox Code Playgroud)
ccp*_*zza 10
您可以使用Automator.app来执行此操作:
\nAutomator.app+ Enter)\n\n注意:您可以使用此方法生成 AppleScript 代码,用于定位窗口、对话框、设置文本、单击按钮等。
\n
这是一个用于记录 UI 操作的随机示例视频。
\n| 归档时间: |
|
| 查看次数: |
17316 次 |
| 最近记录: |