Отправлять нажатия клавиш в самое переднее приложение из изолированного приложения какао

Мне нужно отправить нажатия клавиш на большинство приложений из моего приложения cooca.

У меня уже есть рабочий код для него с использованием CGEventCreateKeyboardEvent() и AXUIElementPostKeyboardEvent(), но он работает, только если приложение не находится в песочнице.

Я искал то же самое в Google, но не нашел рабочего решения.

Я видел, что текстовое приложение и несколько других делают то же самое в изолированной среде, поэтому мне интересно, поможет ли мне кто-нибудь понять, как aText.app и другие могут отправлять нажатия клавиш в изолированной среде.

Спасибо,


person AmitSri    schedule 15.04.2013    source источник
comment
Не могли бы вы предоставить достаточно информации о том, какие приложения делают это и когда мне его воссоздать? Я никогда не видел, чтобы это происходило из изолированного приложения.   -  person Stefan Fisk    schedule 20.04.2013
comment
Пожалуйста, проверьте Text.app, просто напишите Text в Google и проверьте самую первую ссылку. Кажется, что их версия сайта не изолирована, но версия магазина приложений работает в среде песочницы без использования каких-либо временных исключений. пожалуйста, дайте мне знать, если я ошибаюсь. Спасибо   -  person AmitSri    schedule 23.04.2013


Ответы (1)


Это действительно возможно. Я сделал пример приложения доступным здесь — SendKey на GitHub

Я пошел по легкому пути и начал с простого AppleScript:

delay 5

tell application "System Events"
    repeat 10 times
        keystroke "#"
    end repeat
end tell

«Задержка» в сценарии просто дает мне достаточно времени, чтобы сделать текстовый редактор самым передовым приложением. Я бы предложил начать с простого запуска этого скрипта, чтобы посмотреть, что он делает.

Затем я создал проект Xcode, используя шаблон приложения по умолчанию, и написал:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSString*       scriptPath  = [[NSBundle mainBundle] pathForResource:@"sendkey" ofType:@"scpt"];
    NSURL*          scriptURL   = [NSURL fileURLWithPath:scriptPath];
    NSDictionary*   errors;
    NSAppleScript*  script      = [[NSAppleScript alloc] initWithContentsOfURL:scriptURL error:&errors];

    NSLog( @"%@", errors );

    [script executeAndReturnError:&errors];

    NSLog( @"%@", errors );
}

Я проверил это, не включая песочницу, чтобы убедиться, что это работает, и это сработало. Потом я включил Песочницу и, конечно же, она сломалась. Но, к счастью, есть способ обойти это. На данный момент Apple предоставляет временное право под названием com.apple.security.temporary-exception.apple-events. И вы можете запросить предоставление исключения для «com.apple.systemevents». Вот как выглядит мой файл прав:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
   "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>com.apple.security.temporary-exception.apple-events</key>
    <array>
      <string>com.apple.systemevents</string>
    </array>
    <key>com.apple.security.app-sandbox</key>
    <true />
  </dict>
</plist>

Как только я добавил это право в свое изолированное приложение и подписал его, оно снова заработало, как и ожидалось.

Теперь, если вы хотите отправить другие ключи, этот вопрос и ответ продемонстрируют, как создать скрипт на лету — Передача переменных в сценарий Apple.

Конечно, когда все это заработает, вы, вероятно, сможете обратиться к NSApleEventDescriptor и связанным с ним классам для создания события в коде, но я не пробовал эту технику.

Обратите внимание, что Apple предлагает вам сделать следующее при использовании временного права:

Если вы решите не помещать свое приложение в песочницу сейчас или использовать временное право на исключение, используйте систему сообщений об ошибках Apple, чтобы сообщить Apple о проблеме, с которой вы столкнулись. Apple рассматривает запросы функций при разработке платформы OS X. Кроме того, обязательно используйте поле Review Notes в iTunes Connect, чтобы объяснить, почему необходимо исключение.

person ericg    schedule 22.04.2013
comment
Привет, спасибо за ваши усилия. Но у меня есть кое-что, чего я не получаю. Как вы объясняете сценарий Apple, большое спасибо, но реальный вопрос заключается в том, чтобы сделать это без сценария Apple или временного исключения. - person AmitSri; 23.04.2013
comment
Я проверил права aText.app с помощью инструмента codesign и не нашел временного исключения, а когда я добавляю временное исключение в свое тестовое приложение, я вижу, что в правах через codesign кажется, что aText.app не использует временное исключение. - person AmitSri; 23.04.2013
comment
Там может быть что-то очень простое, но это еще не поразило меня. Я все еще пытаюсь найти элегантный способ сделать это. И опубликую, если найду решение, так как это, кажется, довольно популярное требование. :) Благодарность - person AmitSri; 23.04.2013
comment
Можете ли вы предоставить веб-сайт для приложения, с которым вы наблюдаете поведение? Я не знаком с aText.app. - person ericg; 23.04.2013
comment
У вас есть пример бесплатного приложения, которое делает это? Кроме того, какие права есть у приложения? Если не происходит что-то необычное, одно из этих прав позволяет ему делать что-то за пределами ограничений песочницы — и отправка событий другим процессам, безусловно, является нормальным ограничением песочницы. Таким образом, понимание прав atext.app может быть необходимой подсказкой. - person ericg; 23.04.2013
comment
‹?xml version=1.0 encoding=UTF-8?› ‹!DOCTYPE plist PUBLIC -//Apple//DTD PLIST 1.0//EN apple.com/DTDs/PropertyList-1.0.dtd› ‹plist version=1.0› ‹dict› ‹key›com.apple.application-identifier‹/key› ‹ string›KHEMQ2FD9E.com.trankynam.aText‹/string› ‹key›com.apple.developer.ubiquity-container-identifiers‹/key› ‹array› ‹string›KHEMQ2FD9E.com.trankynam.aText‹/string› ‹/ array› ‹key›com.apple.security.app-sandbox‹/key› ‹true/› ‹key›com.apple.security.files.user-selected.read-write‹/key› ‹true/› ‹/ словарь› ‹/plist› - person AmitSri; 23.04.2013
comment
Кто-нибудь действительно получил одобрение приложения, использующего эту технику, в App Store? Я пытался, и мое приложение было отклонено, потому что ему не разрешено общаться с системными событиями через AppleEvents. - person Thomas Tempelmann; 20.12.2013