【发布时间】:2016-06-06 23:12:28
【问题描述】:
我的应用程序的一个功能是检测keyDown 事件并对某些特定键进行处理。
所以,我使用CGEventTapCreate 来解决我的问题,我的代码是这样的:
if let tap = CGEventTapCreate(.CGHIDEventTap, .HeadInsertEventTap, .Default, CGEventMask(1 << CGEventType.KeyDown.rawValue), callBack, nil) {
let runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, tap, 0)
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode)
CGEventTapEnable(tap, true)
CFRunLoopRun()
}
另外,我处理的流程信任如下:
let options = [kAXTrustedCheckOptionPrompt.takeUnretainedValue() as NSString: false]
let processTrusted = AXIsProcessTrustedWithOptions(options)
if processTrusted {
// do CGEventTapCreate()
} else {
// check again 1s later
performSelector("checkMethod", withObject: nil, afterDelay: 1)
}
它将每秒调用一次,直到 processTrusted 为真。
然后奇怪的事情发生了:
当我在 Xcode 中运行应用程序并在 Privacy_Accessibility 中添加信任 Xcode 时,一切正常。但是当我将应用程序存档并将
Export as a Mac Application运行到我的桌面时,CGEventTapCreate() 就不起作用了。
之后我发现了这个帖子Enable access for assistive devices programmatically on 10.9,它注意到我需要在AXIsTrustedProcess()之后重新启动应用程序。
您知道,告诉用户自己重新启动应用程序并不是一个好主意。所以我尝试以编程方式重新启动它并将这些代码添加到if processTrusted {}:
NSWorkspace.sharedWorkspace().launchApplication(NSProcessInfo.processInfo().processName)
NSApplication.sharedApplication().terminate(nil)
也就是说,当我在Privacy_Accessibility 中勾选应用程序时,它会自动重新启动。
又来了一件奇怪的事:
应用程序真正终止并自动启动。但是当它完成重新启动时,应用程序的 Privacy_Accessibility 没有勾选。
真的让我很困惑,希望有人告诉我处理进程信任的正确方法并正确执行CGEventTapCreate()。
谢谢!
【问题讨论】:
-
我很确定您启动的应用程序继承了您当前的权限,但没有官方答案的参考。也就是说,由于您的应用缺少“信任”可访问性,当它调用
launchApplication时,该进程也不是“受信任”的。 -
@Smilin Brian 这是有道理的。据此,我可以以编程方式刷新辅助功能吗?或者是否有一种方法可以启动具有最新可访问性的应用程序?
-
我认为诀窍是让系统启动应用程序,以便 it 成为“父”进程。也许是这样的:
[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"sleep 3 ; /usr/bin/open '%@'", [[NSBundle mainBundle] bundlePath]], nil]]; -
@SmilinBrian 谢谢,你是对的!我使用您的代码,然后致电
NSApplication.sharedApplication().terminate(nil),然后应用程序会以正确的辅助功能重新启动。所以,请回答这个问题,我会设置为正确答案。 -
您是否成功检测到用户何时在系统偏好设置中允许该应用?我正在尝试实现类似的事情,但在重新启动应用程序之前,AXIsProcessTrustedWithOptions 总是返回 false,即使它不应该返回。
标签: objective-c swift macos cocoa cgeventtap