重新启动 OS X 应用程序以在 AXIsProcessTrusted() 为真时执行 CGEventTapCreate()
Relaunch OS X app to execute CGEventTapCreate() when AXIsProcessTrusted() is true
我的应用程序的一项功能是检测 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 为真。
然后奇怪的事情发生了:
When I run the app in Xcode and add trust Xcode in Privacy_Accessibility it all work fine. But When I run it with archive the app and Export as a Mac Application
to my desktop, CGEventTapCreate() just not work.
之后我发现这个 post Enable access for assistive devices programmatically on 10.9,它通知我需要在 AXIsTrustedProcess()
之后重新启动应用程序。
您知道,让用户自己重新启动应用程序并不是一个好主意。所以我尝试以编程方式重新启动它并将这些代码添加到 if processTrusted {}
:
NSWorkspace.sharedWorkspace().launchApplication(NSProcessInfo.processInfo().processName)
NSApplication.sharedApplication().terminate(nil)
换句话说,当我勾选 Privacy_Accessibility
中的应用程序时,它会自动重新启动。
又来了一件奇怪的事情:
The app truly terminate and launch automatically. But when it finish relaunch, the app's Privacy_Accessibility is not tick.
真是让我很困惑,希望有人能告诉我处理进程信任的正确方法并正确执行CGEventTapCreate()
。
谢谢!
轮询 AXIsProcessTrusted
并自动重新启动是一个不错的做法。用户经常对这个过程感到困惑,所以任何有助于简化他们的过程都是好的。
我很确定您启动的应用程序继承了您当前的权限,但没有方便的引用来支持它。我发现在使用 CGEventTap
调试应用程序时,我还必须授予 Xcode 我的应用 requests/requires.
的辅助功能权限
但是您可以通过让系统为您启动您的应用来解决这个问题。尝试:
[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"sleep 3 ; /usr/bin/open '%@'", [[NSBundle mainBundle] bundlePath]], nil]];
我的应用程序的一项功能是检测 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 为真。
然后奇怪的事情发生了:
When I run the app in Xcode and add trust Xcode in Privacy_Accessibility it all work fine. But When I run it with archive the app and
Export as a Mac Application
to my desktop, CGEventTapCreate() just not work.
之后我发现这个 post Enable access for assistive devices programmatically on 10.9,它通知我需要在 AXIsTrustedProcess()
之后重新启动应用程序。
您知道,让用户自己重新启动应用程序并不是一个好主意。所以我尝试以编程方式重新启动它并将这些代码添加到 if processTrusted {}
:
NSWorkspace.sharedWorkspace().launchApplication(NSProcessInfo.processInfo().processName)
NSApplication.sharedApplication().terminate(nil)
换句话说,当我勾选 Privacy_Accessibility
中的应用程序时,它会自动重新启动。
又来了一件奇怪的事情:
The app truly terminate and launch automatically. But when it finish relaunch, the app's Privacy_Accessibility is not tick.
真是让我很困惑,希望有人能告诉我处理进程信任的正确方法并正确执行CGEventTapCreate()
。
谢谢!
轮询 AXIsProcessTrusted
并自动重新启动是一个不错的做法。用户经常对这个过程感到困惑,所以任何有助于简化他们的过程都是好的。
我很确定您启动的应用程序继承了您当前的权限,但没有方便的引用来支持它。我发现在使用 CGEventTap
调试应用程序时,我还必须授予 Xcode 我的应用 requests/requires.
但是您可以通过让系统为您启动您的应用来解决这个问题。尝试:
[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"sleep 3 ; /usr/bin/open '%@'", [[NSBundle mainBundle] bundlePath]], nil]];