gpt4 book ai didi

c - 如何在 OSX 命令行工具、CoreFoundation、C API 中捕获进程空间关键事件?

转载 作者:行者123 更新时间:2023-11-30 16:58:39 25 4
gpt4 key购买 nike

我正在研究如何在C<的进程空间内为OSX无GUI命令行工具实现关键事件捕获和回调/strong>,仅使用 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;
}

最佳答案

下面是一些在终端中运行的 Swift 命令行工具中运行的代码。它会点击通常会路由到 Terminal.app 的事件,或者工具开始运行时最前面的任何进程。它避免了消耗命令键,因此您可以在需要时使用命令周期轻松终止程序。由于 GetFrontProcess() 现已弃用,因此它使用 NSWorkspace 来定位前端进程。

let lock = DispatchQueue(label: "lock")
var events = [CGEvent]()

// track keyboard events using an event tap.
let callback: CGEventTapCallBack = { (tapProxy, eventType, event, _) -> Unmanaged<CGEvent>? in
// don't consume command keys.
if !event.flags.contains(.maskCommand) {
if eventType == .keyDown {
lock.sync {
events.append(event)
}
}
return nil
}
return Unmanaged<CGEvent>.passUnretained(event)
}

let eventMask = CGEventMask((1 << CGEventType.keyDown.rawValue) | (1 << CGEventType.keyUp.rawValue))
if let frontmostProcess = NSWorkspace.shared.frontmostApplication?.processIdentifier, let eventTap = CGEvent.tapCreateForPid(pid: frontmostProcess, place: .headInsertEventTap, options: .defaultTap, eventsOfInterest: eventMask, callback: callback, userInfo: nil) {
let source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, .commonModes)
CGEvent.tapEnable(tap: eventTap, enable: true)
CFRunLoopRun()
}

关于c - 如何在 OSX 命令行工具、CoreFoundation、C API 中捕获进程空间关键事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38659839/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com