Mac OS X'te hangi pencerenin hangi pencerede çalıştığını nasıl belirleyebilirim?


28

Mac OS X'te bir pencereyi oluşturmaktan / yönetmekten hangi işlemin sorumlu olduğunu tanımlamanın mümkün olup olmadığını bilmek istiyorum.

Örneğin, bir uygulamanın birden fazla örneği başlatıldığında, belirli bir pencereye karşılık gelen işlem kimliğini (PID) nasıl alabilirim? Veya başlığı olmayan kalıcı bir iletişim penceresi varsa sahibinin PID'sini nasıl alabilirim?

Windows'ta , bazı verilerle çalışan bir kitaplığı aramanın bir yolunu sağlayan Sysinternals Suite aracını kullanarak mümkün olduğunu biliyorum .

Bu blog yayınında görünene benzer bir mekanizma arıyorum .

Bu durumda, Sysinternals Suite (ve Process Explorer) kullanarak, bir DLL veya alt dizini arayarak (bu durumda, cihazın fiziksel adını kullanarak) hangi DLL / programın web kamerasını kullandığını buldular.

Herhangi bir mekanizma veya program var mı, yoksa Mac OS X için benzer bir şeyi nasıl arayacağınız hakkında bir fikriniz var mı? Hangi sürecin bir pencere başlattığını nasıl belirleyebilirim?


“… Hangi süreç hangi pencereyi gösteriyor…” Windows örneğinize kıyasla kafa karıştırıcı “… hangi DLL / program bir DLL veya alt dize arayarak web kamerasını kullanıyordu.” Açıklamak için lütfen sorunuzu düzenleyebilir misiniz?
JakeGould

1
Bazı işlemler herhangi bir pencere olmadan ve belki de kontrol terminali olmadan da çalışıyor.
Basile Starynkevitch, 19.09.2015

Yanıtlar:


22

Ben kullandım Python komut . Kusursuz değil, ama benim için oldukça iyi çalışıyor.

Komut dosyasının tamamını izinsiz olarak yeniden göndermeyeceğim, ancak işte özet: Bu sistemden pencere bilgilerini toplamak CGWindowListCopyWindowInfoiçin içe aktarılır Quartz, ardından kullanıcıdan istenen pencereyi taşımasını ister, ardından pencere bilgilerini toplar ve gösterir değişenler için bilgi. Dökülen bilgi, işlem kimliğini de içerir kCGWindowOwnerPID.

İşte kod:

#!/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'

Komut 5 saniye aralıklarla konumunu değiştiren pencereyle ilgili bilgileri yazdırır. Böylece çıktı şöyle görünür:

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;
    }
)}

Tam olarak aradığım şey değildi, ama güzel bir başlangıç ​​noktası. Teşekkürler @echo!
I.Cougil,

@ echo on - Bu sitenin gösterdiği şeyleri nasıl uygulayacağımı bilmiyorum, detaylandırılabilir misiniz?
C_K

Python betiğine bağlantı bitmiş gibi görünüyor. Aynı yazıyı
Mark Ebbert

Bu harika bir senaryo. Tanımlayamadığım kötü yazılımları bulmama yardımcı oldu.
Samvel Avanesov

GÜZEL!! Bu gerçekten, uyarı pencereleri açan kötü amaçlı yazılımları tanımlamanın ve kaldırmanın temiz, doğru yoludur. Kötü niyetli olabileceğini bilen bir antivirüs programı kurmaktan ve çalıştırmaktan çok daha iyi.
Jerry Krinock

15

Adında bir araç yaptım 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
    ... ...

Daha sonra pencerenizin yardımını bulmak için grep kullanabilirsiniz.

İşte betiğin kaynak kodu:

#!/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')

Mükemmel çalışıyor. @ Osexp2003 paylaştığınız için teşekkür ederiz!
Hay

10

@ kenorb Komut dosyasının 2 versiyonunu birleştirdim, temel olarak birincisine benziyor, farkı gösteriyor ancak biçimlendirme ikinci. Ayrıca, eğer pencere ekranda değilse - yazdırılmıyor, aksi halde çok fazla çöp veriyor

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)

Fantastik. Mac için xkill'e bir adım daha yakın!
Michael Fox

2
birazpip install pyobjc-framework-Quartz
CupawnTae

Komut dosyasının, çoklu monitör ayarlarıyla% 100 çalışmadığını unutmayın. Bunu bir ekranda bir terminalde çalıştırıp pencereyi başka bir ekranda hareket ettirirseniz, fark içinde listelenen birçok pencereyi göreceksiniz. Hepsi, menü çubuğundaki sistem pencereleri ve simgeler, vb. Gibi görünmektedir. Çalıştırmadan önce terminalinizi ve gizem pencerenizi aynı ekrana taşımak için en iyisidir.
DaveB,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.