在Mac OS X中使用Python查找当前活动窗口
有没有办法用Python在Mac OS X上找到当前活动窗口的应用程序名称呢?
4 个回答
首先,你想要的是窗口名还是应用程序名?这可不是Windows系统——在Mac OS X上,一个应用程序可以有多个窗口。(而且,这在Windows上也已经有几年了,不过我对那里的API是什么样的就不太清楚了。)
其次,你是用Carbon还是Cocoa?
如果你想在Cocoa中获取当前活动窗口:
window = NSApp.mainWindow()
如果你想在Cocoa中获取你的进程名:
appName = NSProcessInfo.processInfo().processName()
补充:哦,我想我知道你想要什么了。你是想要最前面的进程名,对吧?
我觉得在Cocoa中没有办法做到这一点,不过在Carbon中用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会把后面的参数 CopyProcessName
转换成 err, processName = CopyProcessName(…)
,但是Carbon的绑定不依赖于PyObjC(它们是Python 2的核心部分),我也不太清楚PSN该怎么处理。
在OS X 10.7及以上版本中,接受的答案中的方法已经不再推荐使用了。现在推荐的版本是这样的:
from AppKit import NSWorkspace
active_app_name = NSWorkspace.sharedWorkspace().frontmostApplication().localizedName()
print(active_app_name)
这个方法应该可以用:
#!/usr/bin/python
from AppKit import NSWorkspace
activeAppName = NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationName']
print activeAppName
这个方法只在Leopard系统上有效,或者在Tiger系统上,如果你安装了PyObjC,并且在第一行指向了正确的python程序(如果你安装了通用的MacPython,通常会出现问题)。不过,彼得提到的用Carbon的方法可能会更快,因为在Python中第一次导入AppKit的内容会花费一些时间。
如果你在PyObjC应用程序中需要这个功能,我描述的方法会很好且快速,因为你只会经历一次导入AppKit的延迟。如果你想把它做成一个命令行工具,你会发现性能会下降。如果这对你很重要,可能更适合在Xcode中用彼得的代码作为起点,构建一个10行的Foundation命令行工具。