4

我的应用程序的一项功能是检测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() 就不起作用了。

之后我在 10.9 上以编程方式找到了这篇文章 Enable access for assistant devices,它注意到我需要在之后重新启动该应用程序AXIsTrustedProcess()

你知道,告诉用户自己重新启动应用程序并不是一个好主意。所以我尝试以编程方式重新启动它并将这些代码添加到if processTrusted {}

NSWorkspace.sharedWorkspace().launchApplication(NSProcessInfo.processInfo().processName)
NSApplication.sharedApplication().terminate(nil)

换句话说,当我勾选应用程序时Privacy_Accessibility,它会自动重新启动。

另一个奇怪的事情来了:

该应用程序真正终止并自动启动。但是当它完成重新启动时,应用程序的 Privacy_Accessibility 没有勾选。

这真的让我很困惑,我希望有人能告诉我处理流程信任和正确执行的CGEventTapCreate()正确方法。

谢谢!

4

1 回答 1

4

轮询AXIsProcessTrusted和自动重新启动是一个不错的选择。用户经常对这个过程感到困惑,所以任何有助于他们更容易的东西都是好的。

我很确定您启动的应用程序继承了您当前的权限,但没有方便的参考来备份它。我发现在使用CGEventTaps 调试应用程序时,我还必须为 Xcode 提供我的应用程序请求/需要的 Accessibility 权限。

但是您可以通过让系统为您启动应用程序来解决此问题。尝试:

[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"sleep 3 ; /usr/bin/open '%@'", [[NSBundle mainBundle] bundlePath]], nil]];
于 2016-03-01T04:24:55.063 回答