0

我想使用 Swift (Xcode 13.2.1) 发送 Cmd-C 和 Cmd-V 来复制 macOS 11.6 (Big Sur) 中的选定文本,如几个 StackOverflow 帖子中所述(例如如何从最前面的应用程序获取选定的文本在 macOS 中?)。

我仔细按照现有建议为 macOS 安全和隐私框架设置正确的选项:

  • 禁用的应用程序沙盒:
     <key>com.apple.security.app-sandbox</key>
     <false/>
    
  • 添加了“强化运行时”并启用了“Apple 事件”
  • 添加到Info.plist
     <key>NSAppleEventsUsageDescription</key>
     <string>NSApplication</string>
    
  • 每次构建后禁用并启用“安全和隐私”->“辅助功能”中的应用程序复选框。

但是,没有运气。有趣的是,当我在“命令行工具”项目(无 GUI)中使用相同的代码时,一切正常。

这是我的代码:


    let pasteboard = NSPasteboard.general
    
    pasteboard.clearContents()
    
    let source = CGEventSource(stateID: CGEventSourceStateID.hidSystemState)
    
    let cmdKey: UInt16 = 0x38
    let cKey: UInt16 = 0x08
    
    let cmdDown = CGEvent(keyboardEventSource: source, virtualKey: cmdKey, keyDown: true)
    let cmdUp = CGEvent(keyboardEventSource: source, virtualKey: cmdKey, keyDown: false)
    let keyCDown = CGEvent(keyboardEventSource: source, virtualKey: cKey, keyDown: true)
    let keyCUp = CGEvent(keyboardEventSource: source, virtualKey: cKey, keyDown: false)
    
    let loc = CGEventTapLocation.cghidEventTap
    
    cmdDown?.flags = CGEventFlags.maskCommand
    cmdUp?.flags = CGEventFlags.maskCommand
    keyCDown?.flags = CGEventFlags.maskCommand
    keyCUp?.flags = CGEventFlags.maskCommand
    
    cmdDown?.post(tap: loc)
    keyCDown?.post(tap: loc)
    cmdUp?.post(tap: loc)
    keyCUp?.post(tap: loc)
    
    sleep(1)
    
    print("clipboard:")
    let content = pasteboard.string(forType: .string) ?? "" // Default to empty string
    print(content)

任何想法或建议或想法?

最好的,

弗洛克

4

1 回答 1

0

我发现了问题:TCC 拒绝了该请求,因为旧版本的应用程序安装在系统应用程序文件夹中,并且 TCC 已将它的“指纹”存储在“可访问性”下(不知何故)下的给定权限。我不得不删除旧版本并删除 TCC 条目。然后,重建,重新启动应用程序并再次允许“辅助功能”:-> 它工作。

对于社区来说,有趣的可能是我是如何发现这个问题的。我使用以下命令通过检查相关日志走上正轨:

log stream --debug --predicate \
  'subsystem == "com.apple.TCC" AND eventMessage CONTAINS "<my.app.bundle.id>"'
于 2022-01-25T16:52:40.393 回答