从沙盒可可应用程序发送键盘到最前面的应用程序

时间:2013-04-15 14:14:50

标签: cocoa sandbox simulate keystrokes

我需要从我的cooca应用程序向最前面的应用程序发送击键。

我已经使用CGEventCreateKeyboardEvent()AXUIElementPostKeyboardEvent()获得了有效的代码,但只有在app不是沙盒的情况下才有效。

我搜索谷歌的情况相同,但没有找到任何可行的解决方案。

我看到一个Text应用程序和其他几个人在沙盒环境中做同样的事情,所以我想知道,如果有人帮我弄清楚,aText.app和其他人如何能够在沙箱环境中发送击键。

谢谢,

1 个答案:

答案 0 :(得分:3)

这实际上是可行的。我在这里提供了一个示例应用程序 - SendKey at GitHub

我采取了简单的方法,开始使用简单的AppleScript:

delay 5

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

脚本中的“延迟”只是让我有足够的时间使文本编辑器成为最前面的应用程序。我建议从运行此脚本开始,看看它是做什么的。

然后,我使用默认的Application模板创建了一个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>

我将此权利添加到我的沙盒应用程序并对其进行签名后,再次按预期工作。

现在,如果你想发送其他密钥,这个问题&amp;答案将演示如何动态构建脚本 - Passing variables to an applescript

当然,一旦你完成所有这些工作,你可以转向NSAppleEventDescriptor和相关类来在代码中构建事件,但我还没有使用过这种技术。

请注意,Apple建议您在使用临时权利时执行以下操作:

  

如果您选择不立即打包应用程序或使用临时应用程序   例外权利,使用Apple的错误报告系统让Apple   知道你遇到的问题。 Apple考虑功能   请求,因为它开发OS X平台。另外,一定要使用   在iTunes Connect中查看Notes字段以解释异常的原因   需要的。