从沙盒可可应用程序向最前面的应用程序发送击键

Posted

技术标签:

【中文标题】从沙盒可可应用程序向最前面的应用程序发送击键【英文标题】:Send keystrokes to frontmost app from sandboxed cocoa app 【发布时间】:2013-04-07 16:52:26 【问题描述】:

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

我已经有了使用 CGEventCreateKeyboardEvent()AXUIElementPostKeyboardEvent() 的工作代码,但它只有在应用没有被沙盒化的情况下才有效。

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

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

谢谢,

【问题讨论】:

您能否提供足够的信息来说明哪些应用程序会执行此操作以及何时让我重新创建它?我从未见过沙盒应用会发生这种情况。 请检查 aText.app,只需在 Google 中写 aText 并检查第一个链接。似乎他们的网站版本没有沙盒,但应用商店版本已经在沙盒环境中工作,没有使用任何临时异常。如果我错了,请告诉我。谢谢 【参考方案1】:

这实际上是可能的。我在这里提供了一个示例应用程序 - SendKey at 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>

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

现在,如果您想发送其他密钥,此问答将演示如何即时构建您的脚本 - Passing variables to an applescript。

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

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

如果您选择现在不对您的应用进行沙盒处理或使用临时 异常权利,使用苹果的错误报告系统让苹果 了解您遇到的问题。苹果考虑功能 在开发 OS X 平台时提出请求。另外,请务必使用 查看 iTunes Connect 中的“备注”字段以解释异常的原因 需要。

【讨论】:

您好,感谢您的努力。但我有一些我没有得到的东西。正如您对苹果脚本的解释非常感谢,但真正的问题是在没有苹果脚本或临时异常的情况下这样做。 我已经通过 codesign 工具检查了 aText.app 权利,没有发现任何临时异常,而当我在我的测试应用程序中添加临时异常时,我可以通过 codesign 在权利中看到,它似乎 aText.app 没有使用临时异常。 可能有一些非常简单的东西,但我还没有想到。我仍在努力寻找一种优雅的方式来做到这一点。如果找到解决方案,将发布,因为这似乎是一个非常受欢迎的需求。 :) 谢谢 您能否为您看到该行为的应用提供一个网站?我对 aText.app 不熟悉。 真的有人用这种技术获得了应用程序吗?我试过了,但我的应用被拒绝了,因为它不允许通过 AppleEvents 与“系统事件”对话。

以上是关于从沙盒可可应用程序向最前面的应用程序发送击键的主要内容,如果未能解决你的问题,请参考以下文章

如何从沙盒切换到应用内购买

贝宝应用程序。从沙盒到直播

从沙盒应用程序锁定 Macbook 屏幕

如何将文件从沙盒应用程序正确复制到应用程序脚本文件夹?

PayPal - 使用 REST API 从沙盒切换到真实账户

可可沙盒应用程序:Spawn FFMPEG