2016-02-24 5 views
3

Одна из особенностей моего приложения - обнаружить событие keyDown и сделать что-то для некоторых определенных ключей.Перезапустить приложение OS X для выполнения CGEventTapCreate(), когда AXIsProcessTrusted() является истинным

Итак, я использую 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 и добавить доверие Xcode в Privacy_Accessibility все это отлично работает. Но когда я запускаю его с архивом, приложение и 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().

Спасибо!

+0

Я уверен, что приложение, которое вы запускаете, наследует ваши текущие разрешения, но не имеет ссылок на официальный ответ. То есть, поскольку ваше приложение не имеет «доверия» доступности, когда оно вызывает 'launchApplication', этот процесс также не« доверен ». –

+0

@ Смилин Брайан Это имеет смысл. В соответствии с этим, могу ли я программно обновить доступность?Или есть метод, который запустит приложение с его последней доступностью? – Duelsol

+0

Трюк, я думаю, заключается в том, чтобы заставить систему запускать приложение, чтобы * он * был «родительским» процессом. Возможно, что-то вроде: '[NSTask startedTaskWithLaunchPath: @"/bin/sh "аргументы: [NSArray arrayWithObjects: @" - c ", [NSString stringWithFormat: @" sleep 3;/usr/bin/open '% @' ", [ [NSBundle mainBundle] bundlePath]], nil]]; ' –

ответ

3

Опрос AXIsProcessTrusted и автоматическое повторное включение - это приятное прикосновение. Пользователи часто путаются этим процессом, поэтому все, что помогает им облегчить их, хорошо.

Я уверен, что приложение, которое вы запускаете, наследует ваши текущие разрешения, но не имеет ссылок, которые можно было бы поддержать. Я обнаружил, что при отладке приложения с CGEventTap s я также должен предоставить Xcode разрешения на доступ, которые запрашивает/требует мое приложение.

Но вы можете обойти это, запустив систему для запуска вашего приложения. Попробуйте:

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

 Смежные вопросы

  • Нет связанных вопросов^_^