如何以编程方式从10.6上的进程ID获取OSX窗口ID? (使用Applescript,Objective-C等) [英] How to programatically get an OSX window id from a process id on 10.6? (using Applescript, Objective-C, whatever)

查看:85
本文介绍了如何以编程方式从10.6上的进程ID获取OSX窗口ID? (使用Applescript,Objective-C等)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我能做

tell application "Safari" to id of window 1

获取Safari的窗口ID.但是,这仅适用于Applescriptable应用程序.我希望能够编写一个将PID作为输入并输出窗口ID的程序. (以防万一,请依次将窗口ID提供给未记录的"CGSMoveWorkspaceWindowList",以在10.6上的空格之间移动应用程序.)

to get the window ID of Safari. However, this only works for Applescriptable applications. I want to be able to write a program that will take a PID as input and output the window ID. (In case you are curious, this will be used in turn to supply the window ID to the undocumented "CGSMoveWorkspaceWindowList" to move applications between spaces on 10.6.)

根据这个问题,可以做到通过带有Objective-C的OSX可访问性API中未公开的API.不幸的是,作者没有指定有关它的任何其他信息.

According to this question, it is possible to do it via undocumented APIs in the OSX Accessibility API with Objective-C. Unfortunately, the author didn't specify any additional information about it.

当然,我还没有嫁给Objective-C,我只是想以任何可能的方式从PID获取WID.如果有人知道怎么做,另一种可能性是从当前激活的/最前端的进程中获取WID(我有一个命令行工具可以激活给定的PID).

Of course, I'm not married to Objective-C, I just want to get the WID from a PID by any means possible. One other possibility, if anyone knows how, is to get the WID from the currently activated/frontmost process (I have a command line tool to activate a given PID).

感谢weichsel指向我正确的路径,我制作了一个程序来输出所有窗口数据.

Thanks to weichsel pointing me down the right path, I made a program to output all window data.

#include <Carbon/Carbon.h>

// compile as such:
//  gcc -framework carbon -framework foundation GetWindowList.c

int main(int argc, char **argv) {

    CFArrayRef windowList;

    if (argc != 1) {
        printf("usage: %s\n", argv[0]);
        exit(1);
    }

    windowList = CGWindowListCopyWindowInfo(kCGWindowListExcludeDesktopElements, kCGNullWindowID);
    NSLog(CFSTR("Array: %@"), windowList);
    CFRelease(windowList);

}

然后,我用Python解析了所有数据,主要是因为我对在Objective-C中如何做到这一点有0个想法,而且Python可能反而会减少代码行的数量. = D

Then, I used Python to parse all of the data, mostly because I have 0 idea on how to do that in Objective-C, and Python would probably be less lines of code anyway. =D

import os
import re

PID_WID_List = []
temp = os.popen('./GetWindowList 2>&1').read().strip().split('},')
for i in temp:
    match = re.search('kCGWindowOwnerPID = (\d+);', i)
    pid = match.group(1)
    match = re.search('kCGWindowNumber = (\d+);', i)
    wid = match.group(1)
    PID_WID_List.append((pid, wid))

请注意,NSLog将所有内容都写入到system.log中,因此该方法不适用于无限检查循环.

Note that NSLog writes everything to system.log, so this method isn't suitable for an infinite checking loop.

再次感谢weichsel.

Thanks again to weichsel.

推荐答案

您链接到的问题已包含部分答案.
获取窗口的有序列表(包括它们的ID和级别)的Objective-C方法是

The question you linked to already contains a part of the answer.
The Objective-C way to get an ordered list of windows (including their ID and level) is the Quartz Window Services API (CGWindowList...).

Apple提供了"Son of Grab"示例代码项目,该项目使您可以浏览CGWindowListCopyWindowInfo:
返回的所有值.
https://developer.apple.com/library/mac/samplecode/SonOfGrab/

Apple provides the "Son of Grab" sample code project, that allows you to explore all values returned by CGWindowListCopyWindowInfo:
https://developer.apple.com/library/mac/samplecode/SonOfGrab/

虽然窗口信息字典中没有明确包含最前面的"键,但是您应该能够通过过滤kCGWindowLayer == 0元素的列表并选择第一个元素来找到正确的窗口(列表按顺序排在前面-返回).
词典中还包含一个kCGWindowOwnerPID键.

While the window information dictionary doesn't explicitly contain a "frontmost" key, you should be able to find the correct window by filtering the list for elements where kCGWindowLayer == 0 and choose the first element (the list is ordered front-to-back).
The dictionary also contains a kCGWindowOwnerPID key.

这篇关于如何以编程方式从10.6上的进程ID获取OSX窗口ID? (使用Applescript,Objective-C等)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆