Làm cách nào để xác định tiến trình nào đang chạy cửa sổ nào trong Mac OS X?


28

Tôi muốn biết liệu có thể xác định quy trình nào chịu trách nhiệm tạo / quản lý cửa sổ trong Mac OS X.

Ví dụ: khi nhiều phiên bản của một ứng dụng được khởi động, làm cách nào tôi có thể nhận được ID tiến trình (PID) tương ứng với một cửa sổ cụ thể? Hoặc nếu có một cửa sổ hộp thoại phương thức không có tiêu đề, làm thế nào tôi có thể nhận được PID của chủ sở hữu của nó?

Tôi biết trong Windows có thể sử dụng công cụ Sysiternals Suite cung cấp cách tìm kiếm thư viện đang chạy với một số dữ liệu.

Tôi đang tìm kiếm một cơ chế tương tự như cơ chế xuất hiện trong blogpost này .

Trong trường hợp này, bằng cách sử dụng Sysiternals Suite (và Process Explorer), họ đã tìm thấy DLL / chương trình nào đang sử dụng webcam bằng cách tìm kiếm một DLL hoặc chuỗi con (trong trường hợp này, sử dụng tên vật lý của thiết bị).

Vậy có cơ chế hay chương trình nào không, hoặc bạn có ý tưởng nào về cách tìm kiếm thứ gì đó tương tự cho Mac OS X không? Làm thế nào tôi có thể xác định quá trình nào đã khởi chạy một cửa sổ?


Quy trình này đang hiển thị cửa sổ nào, điều này thật khó hiểu khi so sánh với ví dụ Windows của bạn về vụ tấn công mà DLL / chương trình đang sử dụng webcam bằng cách tìm kiếm một DLL hoặc chuỗi con. Bạn có thể chỉnh sửa câu hỏi của mình để làm rõ.
JakeGould

1
Một số quy trình đang chạy mà không có bất kỳ cửa sổ nào, và thậm chí có thể không có thiết bị đầu cuối kiểm soát.
Basile Starynkevitch

Câu trả lời:


22

Tôi đã sử dụng tập lệnh Python . Nó không phải là hoàn hảo, nhưng nó hoạt động khá tốt đối với tôi.

Tôi sẽ không đăng lại toàn bộ tập lệnh mà không được phép, nhưng đây là tóm tắt: Nó sử dụng CGWindowListCopyWindowInfo, được nhập từ Quartz, để thu thập thông tin cửa sổ từ hệ thống, sau đó yêu cầu người dùng di chuyển cửa sổ mong muốn, sau đó thu thập lại thông tin cửa sổ và hiển thị Thông tin cho những người đã thay đổi. Thông tin được kết xuất bao gồm ID tiến trình, như kCGWindowOwnerPID.

Đây là mã:

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

Kịch bản in thông tin cho cửa sổ thay đổi vị trí trong khoảng thời gian 5 giây. Vì vậy, đầu ra trông như thế này:

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

Chà, nó không chính xác như những gì tôi đang tìm kiếm, nhưng nó là một điểm khởi đầu tốt. Cảm ơn bạn @echo trên!
I.Cougil

@echo trên - Tôi không chắc chắn làm thế nào để áp dụng những gì trang web đó hiển thị, bạn có thể giải thích?
C_K

Có vẻ như liên kết đến kịch bản python đã chết. Tôi tin rằng tôi đã tìm thấy cùng một bài đăng trên một trang blog mới ở đây: cadebaba.blogspot.com/2014/04/
Mark

Đây là một kịch bản tuyệt vời. Nó giúp tôi tìm thấy phần mềm khó chịu mà tôi không thể xác định được.
Samvel Avanesov

TỐT ĐẸP!! Đây thực sự là cách sạch sẽ, chính xác để xác định và loại bỏ phần mềm độc hại bật lên các cửa sổ cảnh báo. Tốt hơn nhiều so với việc cài đặt và chạy một chương trình chống vi-rút, mà ai biết, có thể chính nó là phần mềm độc hại.
Jerry Krinock

15

Tôi đã tạo ra một công cụ có tên 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
    ... ...

Sau đó, bạn có thể sử dụng grep để tìm pid của cửa sổ của bạn.

Đây là mã nguồn của tập lệnh:

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

Hoạt động hoàn hảo. Cảm ơn đã chia sẻ @ osexp2003!
Hay

10

@kenorb Tôi đã kết hợp 2 phiên bản tập lệnh của bạn, về cơ bản nó hoạt động như phiên bản đầu tiên, cho thấy sự khác biệt nhưng định dạng là từ phiên bản thứ hai. Ngoài ra nếu cửa sổ không xuất hiện trên màn hình - nó sẽ không được in, nếu không, nó sẽ cho quá nhiều rác

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)

Tuyệt diệu. Một bước gần hơn với xkill cho Mac!
Michael Fox

2
với một chút củapip install pyobjc-framework-Quartz
CupawnTae

Lưu ý rằng tập lệnh không hoạt động 100% với các thiết lập đa màn hình. Nếu bạn chạy cái này trong một thiết bị đầu cuối trên một màn hình và sau đó di chuyển cửa sổ trên một màn hình khác, bạn sẽ thấy nhiều cửa sổ được liệt kê trong diff. Tất cả chúng dường như là các cửa sổ hệ thống và biểu tượng trong thanh menu, v.v. Tốt nhất để di chuyển thiết bị đầu cuối của bạn và cửa sổ bí ẩn đến cùng một màn hình trước khi chạy.
DaveBurns
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.