简体   繁体   中英

Relaunch OS X app to execute CGEventTapCreate() when AXIsProcessTrusted() is true

One of my app's feature is detect keyDown event and do someting for some specific keys.

So, I use CGEventTapCreate to solve my problem and my code is like this:

   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()
   }

Also, I deal with the process trust like:

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)
}

It will be called per second until processTrusted is true.

Then strange thing happened:

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.

After that I found this post Enable access for assistive devices programmatically on 10.9 , it notice me that I need to relaunch the app after AXIsTrustedProcess() .

You know, it's not a good idea to tell users to relaunch the app themselves. So I try to relaunch it programmatically and add these code into if processTrusted {} :

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

In other words, when I tick the app in Privacy_Accessibility , it will relaunch automatically.

Here comes another strange thing:

The app truly terminate and launch automatically. But when it finish relaunch, the app's Privacy_Accessibility is not tick.

It's really confuse me a lot, I hope someone will tell me the right way to deal with process trust and execute CGEventTapCreate() correctly.

Thanks!

Polling AXIsProcessTrusted and automatically relaunching is a nice touch. Users are often confused by this process, so anything that helps make it easier for them is good.

I'm pretty sure that an application that you launch inherits your current permissions, but don't have references handy to back that up. I have found that when debugging an application with CGEventTap s, I also have to give Xcode the Accessibility permissions that my app requests/requires.

But you can work around this by getting the system to launch your app for you. Try:

[NSTask launchedTaskWithLaunchPath:@"/bin/sh" arguments:[NSArray arrayWithObjects:@"-c", [NSString stringWithFormat:@"sleep 3 ; /usr/bin/open '%@'", [[NSBundle mainBundle] bundlePath]], nil]];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM