沙盒应用程序中的AppleScript`activate`不会将窗口置于前台

时间:2018-09-19 20:39:44

标签: macos cocoa applescript appstore-sandbox entitlements

我正在尝试从沙盒式macOS应用程序中打开“系统偏好设置”,以便用户可以手动启用某个偏好设置。

  

AppleScript activate

     
    

将应用程序置于最前面,必要时启动它。

  

我正在运行macOS 10.13.6和Xcode 10.0。部署目标设置为OS X 10.11。

我从沙盒应用程序运行以下AppleScript:

let script = """
             tell application "System Preferences"
                 activate
                 set current pane to pane id "com.apple.preferences.extensions"
             end tell
             """
let appleScript = NSAppleScript(source: script)
var errorInfo: NSDictionary? = nil
appleScript?.executeAndReturnError(&errorInfo)

我还添加了一个脚本目标沙箱权利,使“系统偏好设置”可以显示窗格:

<key>com.apple.security.scripting-targets</key>
<dict>
    <key>com.apple.systempreferences</key>
    <array>
        <string>preferencepane.reveal</string>
    </array>
</dict>

添加权利后,此方法一定有效。如果关闭了“系统偏好设置”应用程序,则会启动它并打开正确的窗格。

errorInfo字典为nil,没有错误信息。

在控制台中,我看到一条消息,which is perhaps unrelated log spam

  

AppleEvents:收到了mach msg,它不是getMemoryReference中预期的复杂类型。

System Preferences window does not activate or come to foreground.

但是,该应用程序未激活。系统偏好设置窗口不位于最前面。该应用程序导航到正确的选项卡,但未显示为activate状态的文档。它保留在任何其他前景窗口的后面。

在关闭系统偏好设置的情况下,该应用程序确实会启动。但是,直到您单击停靠图标,该窗口才会添加到前景背景中的屏幕上。然后出现一个窗口,已经导航到正确的窗格。

为什么该应用程序无法激活?

是否还有其他需要激活“系统偏好设置”窗口的沙盒权利?

2 个答案:

答案 0 :(得分:1)

我建议您执行以下操作(这已由我在macOS Mojave上进行了测试,并且可以正常工作)。

  1. 打开Script Editor
  2. 将脚本代码粘贴到其中(当然,不带外部引号)
  3. 将其另存为应用
  4. 转到Finder中保存它的位置,然后用鼠标右键单击“显示包装内容”。
  5. 转到“内容”并在Xcode中打开Info.plist
  6. 检查此应用程序使用的权利,尤其是隐私-AppleEvents发送使用说明NSAppleEventsUsageDescription)。
  7. 在您的应用程序中进行复制,但请不要使用Applescript应用程序默认使用的所有权利,而仅使用您真正需要的权利。

答案 1 :(得分:1)

对我来说似乎是个错误,脚本中不允许使用activate命令。但是,我在一个简单的测试应用程序中确认,即使我重现了您描述的行为,也可以使用NSWorkspace启动系统偏好设置来解决此问题。如果已启动该应用程序,则此过程会产生副作用。因此,在AppleScript执行之前,在 之前添加如下代码:

NSWorkspace.shared.launchApplication(withBundleIdentifier: "com.apple.systempreferences", options: [], additionalEventParamDescriptor: nil, launchIdentifier: nil)

还有其他奇怪的地方:如果您在脚本中保留了“激活”,似乎会导致正在运行的应用重新激活。因此,完整的解决方法似乎需要在代码中添加类似于上面的内容,并从脚本中删除“激活”。