如何在macOS下用C语言获取接收按键的应用程序ID?
在C语言中获取macOS当前前台应用的ID和名称
刚接触macOS开发的话,确实会对系统API的调用有点懵,别担心,我给你两种可行的方案,帮你拿到当前聚焦窗口所属应用的ID(PID)和名称:
方案一:纯C语言(Core Graphics + Core Foundation)
这个方案完全用C语言实现,依赖Core Graphics和Core Foundation框架,适合严格要求纯C的场景。
代码示例
#include <CoreGraphics/CoreGraphics.h> #include <CoreFoundation/CoreFoundation.h> #include <stdio.h> int main() { // 获取所有屏幕上的窗口信息,排除桌面元素 CFArrayRef windowList = CGWindowListCopyWindowInfo(kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, kCGNullWindowID); if (!windowList) { fprintf(stderr, "Failed to get window list\n"); return 1; } CFIndex count = CFArrayGetCount(windowList); for (CFIndex i = 0; i < count; i++) { CFDictionaryRef windowInfo = CFArrayGetValueAtIndex(windowList, i); // 筛选前台窗口:层级为0且处于屏幕可见状态 CFNumberRef layerRef = CFDictionaryGetValue(windowInfo, kCGWindowLayer); int layer = 0; CFNumberGetValue(layerRef, kCFNumberIntType, &layer); if (layer != 0) continue; CFBooleanRef isOnscreenRef = CFDictionaryGetValue(windowInfo, kCGWindowIsOnscreen); if (!isOnscreenRef || !CFBooleanGetValue(isOnscreenRef)) continue; // 提取应用名称和PID CFStringRef appNameRef = CFDictionaryGetValue(windowInfo, kCGWindowOwnerName); CFNumberRef pidRef = CFDictionaryGetValue(windowInfo, kCGWindowOwnerPID); pid_t pid = 0; CFNumberGetValue(pidRef, kCFNumberIntType, &pid); // 转换为C字符串输出 char appName[256]; CFStringGetCString(appNameRef, appName, sizeof(appName), kCFStringEncodingUTF8); printf("前台应用名称: %s\n", appName); printf("前台应用PID: %d\n", pid); break; // 第一个层级0的窗口即为当前前台窗口 } CFRelease(windowList); return 0; }
编译运行
在终端执行以下命令编译:
clang -o get_front_app get_front_app.c -framework CoreGraphics -framework CoreFoundation
运行生成的可执行文件:
./get_front_app
方案二:C + Objective-C混编(NSWorkspace)
如果不严格限制纯C,这种方法更简洁直接,借助Cocoa框架的NSWorkspace类,它直接提供了frontmostApplication方法获取前台应用。
代码示例
#include <stdio.h> #import <Cocoa/Cocoa.h> int main() { // 手动初始化Cocoa环境(终端程序需自行处理) [NSApplication sharedApplication]; NSRunningApplication *frontApp = [NSWorkspace sharedWorkspace].frontmostApplication; if (!frontApp) { fprintf(stderr, "Failed to get frontmost application\n"); return 1; } printf("前台应用名称: %s\n", [frontApp.localizedName UTF8String]); printf("前台应用PID: %d\n", frontApp.processIdentifier); printf("应用Bundle ID: %s\n", [frontApp.bundleIdentifier UTF8String]); return 0; }
编译运行
终端编译命令:
clang -o get_front_app_objc get_front_app_objc.m -framework Cocoa
运行:
./get_front_app_objc
注意事项
- 如果需要持续监听前台应用的切换,你可以注册
NSWorkspaceDidActivateApplicationNotification通知,但需要额外处理事件循环。 - 普通获取前台应用信息不需要特殊权限,但若涉及监听全局按键,可能需要在系统偏好设置中开启辅助功能权限。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

