Я хотел бы узнать, возможно ли определить, какой процесс отвечает за создание/управление окном в Mac OS X.
Например, когда запущено несколько экземпляров приложения, как получить идентификатор процесса (PID), соответствующий одному конкретному окну? Или, если есть модальное диалоговое окно без заголовка, как получить PID его владельца?
Я знаю, что в Windows это возможно с помощьюSysinternals Suiteинструмент, который позволяет искать библиотеку, работающую с некоторыми данными.
Я ищу механизм, похожий на тот, который изображен вэтот блогпост.
В этом случае с помощью Sysinternals Suite (и Process Explorer) они обнаружили, какая DLL/программа использовала веб-камеру, выполнив поиск DLL или подстроки (в данном случае с использованием физического имени устройства).
Так есть ли какой-то механизм или программа, или у вас есть какие-либо идеи о том, как искать что-то подобное для Mac OS X? Как я могу определить, какой процесс запустил окно?
решение1
Я использовалэтот скрипт Python 2. Это не совсем надежно, но мне подходит.
Вот краткое изложение того, что он делает: он использует CGWindowListCopyWindowInfo
, который импортируется из Quartz
, для сбора информации об окнах из системы, затем просит пользователя переместить желаемое окно, затем снова собирает информацию об окнах и показывает информацию для тех, которые изменились. Сбрасываемая информация включает идентификатор процесса, как 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 Developer Tools и называетсяAccessibility Inspector
решение4
Вы можете использоватьAutomator.приложениедля этого:
- Запустить Automator (в центре внимания введите
Automator.app
+ Enter) - Создайте новый рабочий процесс.
- В меню выберитеРабочий процесс>Записывать(или нажмите кнопку