为何macOS中AXUIElement无法获取可用辅助功能操作?
问题分析与解决
你遇到的核心问题是:系统级辅助功能元素(AXUIElementCreateSystemWide()返回的对象)本身没有可执行的动作,它只是一个根容器,用来遍历系统中的其他可交互元素(比如窗口、按钮、文本框等),所以返回空动作列表是符合预期的。
为什么你的代码返回空列表
AXUIElementCreateSystemWide()获取的是整个系统的根 accessibility 元素,它的作用是作为起点去查找其他具体的UI元素,比如应用窗口、菜单栏控件等,本身并不具备可触发的动作(比如点击、滚动这类操作),所以AXUIElementCopyActionNames返回空数组是正常行为,并非代码错误。
修改后的示例代码
如果你想看到实际的动作列表,可以尝试获取一个具体的可交互元素,比如当前活跃应用的窗口,示例代码如下:
import AppKit // 获取系统级元素作为根容器 let systemWideElement = AXUIElementCreateSystemWide() // 获取当前活跃应用的PID guard let frontmostApp = NSWorkspace.shared.frontmostApplication, let pid = frontmostApp.processIdentifier as? pid_t else { print("无法获取前台应用") exit(1) } // 创建前台应用的accessibility元素 let appElement = AXUIElementCreateApplication(pid) // 获取该应用的动作列表(如果有的话) var appActions: CFArray? let appErr = AXUIElementCopyActionNames(appElement, &appActions) if appErr == .success, let actions = appActions as? [String] { print("前台应用的可用动作: \(actions)") } else { print("获取应用动作失败: \(appErr.rawValue)") } // 进一步获取应用的窗口列表,再查看窗口的动作 var windows: CFArray? let windowErr = AXUIElementCopyAttributeValue(appElement, kAXWindowsAttribute as CFString, &windows) if windowErr == .success, let windowList = windows as? [AXUIElement] { guard let firstWindow = windowList.first else { print("应用没有打开的窗口") exit(1) } var windowActions: CFArray? let winErr = AXUIElementCopyActionNames(firstWindow, &windowActions) if winErr == .success, let winActs = windowActions as? [String] { print("第一个窗口的可用动作: \(winActs)") } else { print("获取窗口动作失败: \(winErr.rawValue)") } } else { print("获取窗口列表失败: \(windowErr.rawValue)") }
关于权限与Entitlements的补充
- 你已经确认
AXIsProcessTrusted()返回true,说明辅助功能权限已经正确授予,这部分没问题。 - 如果你的应用开启了沙盒,需要在
.entitlements文件中添加对应的权限:- 若要访问其他应用的accessibility元素,需添加
com.apple.security.temporary-exception.apple-events(针对特定应用),或者确保沙盒的“辅助功能”权限开启(在Xcode的Signing & Capabilities中配置)。
- 若要访问其他应用的accessibility元素,需添加
内容的提问来源于stack exchange,提问作者ihales
相关产品推荐
相关产品推荐

