मैक ओएस एक्स में किस विंडो पर कौन सी प्रक्रिया चल रही है, इसकी पहचान कैसे करें?


28

मैं जानना चाहता हूं कि क्या मैक ओएस एक्स में एक विंडो बनाने / प्रबंधित करने के लिए कौन सी प्रक्रिया जिम्मेदार है, इसकी पहचान करना संभव है।

उदाहरण के लिए, जब एक आवेदन के कई उदाहरण शुरू किए जाते हैं, तो मैं एक विशिष्ट विंडो के अनुरूप प्रक्रिया आईडी (पीआईडी) कैसे प्राप्त कर सकता हूं? या अगर कोई शीर्षक के बिना एक मोडल संवाद खिड़की है, तो मैं उसके मालिक की पीआईडी ​​कैसे प्राप्त कर सकता हूं?

मुझे पता है कि विंडोज में Sysinternals Suite टूल का उपयोग करना संभव है जो एक लाइब्रेरी की खोज करने का एक तरीका प्रदान करता है जो कुछ डेटा के साथ चल रहा है।

मैं इस ब्लॉगपोस्ट में दिखाई देने वाले के समान एक तंत्र की तलाश कर रहा हूं ।

इस मामले में, Sysinternals Suite (और प्रोसेस एक्सप्लोरर) का उपयोग करते हुए, उन्होंने पाया कि DLL / प्रोग्राम एक DLL की खोज करके या (इस मामले में, डिवाइस के भौतिक नाम का उपयोग करके) वेब कैमरा का उपयोग कर रहा था।

तो क्या कोई तंत्र या कार्यक्रम है, या क्या आपके पास मैक ओएस एक्स के लिए कुछ इसी तरह की खोज करने के बारे में कोई विचार है? मैं कैसे पहचान सकता हूं कि किस प्रक्रिया ने एक विंडो लॉन्च की है?


"... कौन सी प्रक्रिया किस विंडो को दिखा रही है ..." यह आपके विंडोज उदाहरण की तुलना में भ्रमित है "... जो DLL / प्रोग्राम एक DLL या विकल्प की खोज करके वेबकेम का उपयोग कर रहा था।" क्या आप कृपया अपने प्रश्न को स्पष्ट करने के लिए संपादित कर सकते हैं।
जेकगोल्ड

1
कुछ प्रक्रियाएं बिना किसी विंडो के चल रही हैं, और शायद एक नियंत्रित टर्मिनल के बिना भी।
बेसिल स्टारीनेवविच

जवाबों:


22

मैंने पायथन लिपि का उपयोग किया है । यह मूर्खतापूर्ण नहीं है, लेकिन यह मेरे लिए बहुत अच्छा काम करता है।

मैं पूरी स्क्रिप्ट को बिना अनुमति के नहीं दूंगा, लेकिन यहां एक सारांश है: यह उपयोग करता है 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;
    }
)}

खैर, यह बिल्कुल वैसा नहीं है जैसा मैं देख रहा था, बल्कि यह एक अच्छा शुरुआती बिंदु है। शुक्रिया @echo on!
२३:३५ बजे

@ पर - मुझे यकीन नहीं है कि उस साइट को कैसे लागू किया जाए, क्या आप बता सकते हैं?
C_K

ऐसा लगता है कि अजगर स्क्रिप्ट की कड़ी मर चुका है। मेरा मानना ​​है कि मुझे एक नया ब्लॉग साइट पर एक ही पोस्ट यहाँ मिली
Mark Ebbert

यह एक अद्भुत पटकथा है। इसने मेरे खराब सॉफ्टवेयर को खोजने में मदद की जिसे मैं पहचान नहीं सका।
सैमवेल अवनेसोव

अच्छा !! यह मैलवेयर को पहचानने और हटाने के लिए वास्तव में साफ, सही तरीका है जो अलर्ट विंडो को पॉप अप करता है। एंटीवायरस प्रोग्राम को स्थापित करने और चलाने से बहुत बेहतर है, जो जानता है, स्वयं मैलवेयर हो सकता है।
जेरी क्रिनॉक

15

मैंने एक टूल बनाया जिसका नाम है 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
    ... ...

फिर आप अपनी खिड़की की पिड खोजने के लिए grep का उपयोग कर सकते हैं।

यहाँ स्क्रिप्ट का स्रोत कोड है:

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

अच्छी तरह से काम। @ Osexp2003 को शेयर करने के लिए धन्यवाद!
हेय

10

@kenorb मैंने स्क्रिप्ट के अपने 2 संस्करणों को संयोजित किया, मूल रूप से यह पहले वाले की तरह काम करता है, अंतर दिखा रहा है लेकिन स्वरूपण दूसरे से है। इसके अलावा अगर खिड़की स्क्रीन पर नहीं है - इसे प्रिंट नहीं किया जा रहा है, अन्यथा यह बहुत अधिक कचरा देता है

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)

बहुत खुबस। मैक के लिए xkill के करीब एक कदम!
माइकल फॉक्स

2
के साथ थोड़ाpip install pyobjc-framework-Quartz
CupawnTae

ध्यान दें कि स्क्रिप्ट मल्टी-मॉनिटर सेट अप के साथ 100% काम नहीं करती है। यदि आप इसे एक स्क्रीन पर एक टर्मिनल में चलाते हैं और फिर विंडो को दूसरी स्क्रीन पर ले जाते हैं, तो आपको अंतर में सूचीबद्ध कई विंडो दिखाई देंगी। इन सभी को मेनू बार में सिस्टम विंडो और आइकन प्रतीत होते हैं, आदि चलने से पहले अपने टर्मिनल और मिस्ट्री विंडो को एक ही स्क्रीन पर ले जाने के लिए सबसे अच्छा है।
डेवबर्न्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.