You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:47:31