使用Python在Mac OS X中查找当前活动窗口

有没有办法在Mac OS X上使用Python在特定时间查找当前活动窗口的应用程序名称?

这应该工作:

#!/usr/bin/python from AppKit import NSWorkspace activeAppName = NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationName'] print activeAppName 

只有在Leopard或Tiger上运行,如果你已经安装了PyObjC,并且碰巧指向第一行的正确的python二进制文件(如果你安装了通用的MacPython,那么你可能希望在Tiger上执行这个操作)。 但是Peter用Carbon的方式做这个回答可能会快很多,因为从AppKit导入任何东西需要一段时间,或者更准确地说,在Python过程中第一次从AppKit导入某些内容需要一段时间。

如果您在PyObjC应用程序中需要这个,我所描述的将会非常快速,因为您只经历一次导入AppKit的延迟。 如果你需要这个作为一个命令行工具,你会注意到性能的影响。 如果这与你有关,那么你最好使用Peter的代码作为起点,在Xcode中构build一个10行的基础命令行工具。

接受的答案中的方法在OS X 10.7+中已弃用。 目前的推荐版本如下:

 from AppKit import NSWorkspace active_app_name = NSWorkspace.sharedWorkspace().frontmostApplication().localizedName() print(active_app_name) 

首先,你需要窗口还是应用程序名称? 这不是Windows – Mac OS X上的应用程序进程可以有多个窗口。 (此外,几年以来,Windows也是如此,尽pipe我不知道API是什么样的。)

其次,碳还是cocoa?

要获得cocoa的活动窗口:

 window = NSApp.mainWindow() 

要在Cocoa中获得您的stream程的名称:

 appName = NSProcessInfo.processInfo().processName() 

编辑:哦,我想我知道你想要什么。 最前面的过程的名字,对吧?

我不认为在Cocoa中有办法做到这一点,但是在C中如何做到这一点:

 ProcessSerialNumber psn = { 0L, 0L }; OSStatus err = GetFrontProcess(&psn); /*error check*/ CFStringRef processName = NULL; err = CopyProcessName(&psn, &processName); /*error check*/ 

记住CFRelease(processName)当你完成它。

我不确定在Python中是什么样的,或者甚至是可能的。 Python没有指针,这使得棘手。

我知道PyObjC会把后面的参数CopyProcessNameerr, processName = CopyProcessName(…) ,但是Carbon绑定不依赖PyObjC(它们是Python 2的核心部分),我不确定你做了什么关于PSN的方式。

我需要Python脚本中的当前最前面的应用程序,将窗口很好地排列在我的屏幕上(请参阅move_window )。

当然,完整的功劳归功于彼得! 但是这里是完整的程序:

 #include <Carbon/Carbon.h> int main(int, char) { ProcessSerialNumber psn = { 0L, 0L }; OSStatus err = GetFrontProcess(&psn); CFStringRef processName = NULL; err = CopyProcessName(&psn, &processName); printf("%s\n", CFStringGetCStringPtr(processName, NULL)); CFRelease(processName); } 

gcc -framework Carbon filename.c构buildgcc -framework Carbon filename.c