【发布时间】:2010-09-27 05:53:30
【问题描述】:
有没有办法在 Mac OS X 上使用 Python 在给定时间查找当前活动窗口的应用程序名称?
【问题讨论】:
标签: python objective-c cocoa macos
有没有办法在 Mac OS X 上使用 Python 在给定时间查找当前活动窗口的应用程序名称?
【问题讨论】:
标签: python objective-c cocoa macos
首先,您想要窗口还是应用程序名称?这不是 Windows——Mac OS X 上的一个应用程序进程可以有多个窗口。 (此外,Windows 几年来也是如此,尽管我不知道 API 是什么样子的。)
第二,碳还是可可?
在 Cocoa 中获取活动窗口:
window = NSApp.mainWindow()
在 Cocoa 中获取进程的名称:
appName = NSProcessInfo.processInfo().processName()
编辑:哦,我想我知道你想要什么。最前面的进程的名字吧?
我认为在 Cocoa 中没有办法做到这一点,但这里是如何在 C 中的 Carbon 中做到这一点:
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 的任何一种方式。
【讨论】:
CFRelease 对于 PyObjC 不是必需的。 PyObjC 为您处理调用,AFAIK。
这应该可行:
#!/usr/bin/python
from AppKit import NSWorkspace
activeAppName = NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationName']
print activeAppName
仅适用于 Leopard 或 Tiger 如果您安装了 PyObjC 并且恰好在第一行指向正确的 python 二进制文件(如果您安装了通用 MacPython,则情况并非如此,您可能希望在 Tiger 上执行此操作)。但是 Peter 对 Carbon 方法的回答可能会快很多,因为在 Python 中从 AppKit 导入任何东西需要一段时间,或者更准确地说,在 Python 进程中第一次从 AppKit 导入一些东西需要一段时间。
如果您在 PyObjC 应用程序中需要它,我所描述的将非常有效且快速,因为您只体验一次导入 AppKit 的延迟。如果您需要它作为命令行工具工作,您会注意到性能下降。如果这与您相关,您最好使用 Peter 的代码作为起点,在 Xcode 中构建一个 10 行的 Foundation 命令行工具。
【讨论】:
我需要一个 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 构建
【讨论】:
$.NSWorkspace.sharedWorkspace.activeApplication.objectForKey('NSApplicationName').UTF8String;。你需要先导入这个:ObjC.import('AppKit').
已接受答案中的方法在 OS X 10.7+ 中已弃用。当前推荐的版本如下:
from AppKit import NSWorkspace
active_app_name = NSWorkspace.sharedWorkspace().frontmostApplication().localizedName()
print(active_app_name)
【讨论】: