【发布时间】:2016-07-29 13:12:58
【问题描述】:
我正在研究如何在 C,仅使用CoreFoundation,(没有Cocoa,没有NSEvents)。经过一些研究,我可以轻松地将这个 MCVE 放在“全局级别”(这需要以 root 权限运行程序),但无法弄清楚如何捕获和处理仅限程序的进程空间。我也没有找到关于如何做到这一点的文档。我在 SO 上发现了这个领域的一些问题,但所有这些问题都是基于 Cocoa API 的。我很乐意提供所需的任何其他信息。
// gcc -Wall -o test test.c -framework ApplicationServices
// sudo test
#include <ApplicationServices/ApplicationServices.h>
CGEventRef testEventCallback(CGEventTapProxy proxy,
CGEventType type,
CGEventRef event,
void *refcon)
{
printf( " Event Type: %d\n", type );
return event;
}
int main(int argc, char *argv[])
{
CFMachPortRef eventPort;
CFRunLoopSourceRef eventSrc;
CFRunLoopRef runLoop;
CGEventMask mask = CGEventMaskBit(kCGEventKeyDown) | CGEventMaskBit(kCGEventKeyUp);
eventPort = CGEventTapCreate(kCGSessionEventTap,
kCGHeadInsertEventTap,
kCGEventTapOptionListenOnly,
mask,
testEventCallback,
NULL );
if ( eventPort == NULL ){
printf( "NULL eventPort\n" );
return 1;
}
eventSrc = CFMachPortCreateRunLoopSource(NULL, eventPort, 0);
if ( eventSrc == NULL ){
printf( "NULL eventSrc\n" );
return 1;
}
runLoop = CFRunLoopGetCurrent();
if ( runLoop == NULL ){
printf( "NULL runLoop\n" );
return 1;
}
CFRunLoopAddSource(runLoop, eventSrc, kCFRunLoopDefaultMode);
CFRunLoopRun();
return 0;
}
【问题讨论】:
-
“程序的进程空间”是什么意思?
-
感谢@Willeke 的提问:我的意思是“不是系统范围的”,但仅适用于特定程序。我不需要监视用户放入其他打开程序的关键事件,而只需要监视这个特定的命令行工具。希望我现在更清楚一点。
-
CGEventTapCreate的文档链接到事件点击位置。在底部它说“除了上面描述的三个点击点之外,还可以放置一个事件点击,将带注释的事件传递给特定的应用程序。有关更多信息,请参阅函数 CGEventTapCreateForPSN。”。 -
这是非常有价值的信息,@Willeke。我设法通过调用
GetFrontProcess()来修改获取PSN 的代码。但是我不明白为什么它仍然需要 超级用户权限 才能运行CGEventTapCreateForPSN?sudo test…我一定遗漏了一些非常明显的东西。 -
命令行工具从来没有这样的键盘焦点。如果您从终端运行它,那么它是具有键盘焦点的终端。在命令行工具的进程空间中不存在关键事件。
标签: c macos core-foundation