如何在 Swift 应用程序启动后 post 一个 Quartz 事件?

How to post a Quartz Event after Swift application launch?

我正在编写一个简单的 Cocoa 应用程序,它将从 AppleScript 启动,只是为了 post 一个 Quartz Event 到另一个应用程序。

不需要用户界面,所以我从 Interface Builder 中删除了 window,并从 Application Delegate 中删除了它的出口。我从方法 applicationDidFinishLaunching(_:) 调用私有方法 postClickEvent()。我在 mouseCursorPosition (x: 0, y: 0) 处使用 nil mouseEventSource 初始化 leftMouseDownleftMouseUp CGEvent,在 cghidEventTap.

处使用 post 它们
import Cocoa  
  
@NSApplicationMain  
class AppDelegate: NSObject, NSApplicationDelegate {  
  
    func applicationDidFinishLaunching(_ aNotification: Notification) {  
        postClickEvent()  
    }  
  
    func applicationWillTerminate(_ aNotification: Notification) {  
    }  
  
    private func postClickEvent() {  
        let point = CGPoint(x: 0, y: 0)  
  
        let leftMouseDownEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseDown, mouseCursorPosition: point, mouseButton: .left)  
        let leftMouseUpEvent = CGEvent(mouseEventSource: nil, mouseType: .leftMouseUp, mouseCursorPosition: point, mouseButton: .left)  
  
        leftMouseDownEvent?.post(tap: .cghidEventTap)  
        leftMouseUpEvent?.post(tap: .cghidEventTap)  
    }  
}

我希望应用程序在启动后立即单击左上角并打开 Apple 菜单,但它并没有发生。

我可以想到几种可能的解决方案。

默认使用沙箱是 Swift Package Manager 在 Xcode 9.0 中的一项新功能。

Updated package manifest interpretation and package builds on macOS to use a sandbox, which prevents network access and file system modification. This helps mitigate the effect of maliciously crafted manifests. (31107213)

Xcode Release Notes

但是 Quartz Events 与 App Sandbox 不兼容。

You cannot sandbox an app that controls another app. Posting keyboard or mouse events using functions like CGEventPost offers a way to circumvent this restriction, and is therefore not allowed from a sandboxed app.

App Sandbox Design Guide

运行 该应用在控制台中留下沙盒违规日志消息,表明该应用被拒绝了人机界面设备控制。

Console

在 Xcode 目标编辑器中禁用 App Sandbox 允许 post Quartz 事件。

Xcode