我找到了在 iOS 中做同样事情的方法。
我知道这不是对你的问题的直接答案,但我会尝试解释我在 iOS 中找到它的方法,并希望你能够在 macOS 中做同样的事情。另外,这可能对其他读者有用......
我首先猜测该过程本身正在创建AXUIElementRef
,所以当我请求具有以下属性的可访问性属性时,它必须创建它们AXUIElementRef
值,例如kAXUIElementAttributeChildren
.
然后我创建了一个应用程序,并进行了 dlsym'ed_AXUIElementCreateAppElementWithPid(int pid)
,调用它[[NSProcessInfo processInfo] processIdentifier]
。
我收到根了AXUIElementRef
,然后我将其传递给AXError AXUIElementCopyMultipleAttributeValues(AXUIElementRef element, CFArrayRef attributes, AXCopyMultipleAttributeOptions options, CFArrayRef _Nullable *values)
,要求kAXUIElementAttributeChildren
,并且它有效(应该在主线程上运行)!
我开始调试AXUIElementCopyMultipleAttributeValues
仔细调用汇编代码,其过程非常相似(当然,这是非常伪代码......):
// serialize the arguments for MIG call
if (axUIElementRef->pid == self pid) {
// that's good that we are calling our own process, we can easily keep debugging!
_MIGXAAXUIElementCopyMultipleAttributeValues(serialized arguments) {
// Get the original element from the AXUIElementRef:
UIView* view = _AXElementForAXUIElementUniqueId(id);
[view accessibilityAttributeValue:kAXUIElementAttributeChildren] {
[view _accessibilityUserTestingChildren] {
// since this is the UIApplication element, it just gets the windows:
NSArray*<UIWindow*> winArr = [(UIApplication*)view _accessibilityWindows];
// for each value in result, convert to AX value:
...
AXConvertOutgoingValue(winArr) {
// For each UIView, convert to AXUIElementRef:
AXUIElementRef e = _AXCreateAXUIElementWithElement(winArr[i]);
}
}
}
}
} else {
// Do the same only if we are entitled, and outside our process
}
所以,在 iOS 中,你只需调用AXUIElementRef _AXCreateAXUIElementWithElement(UIView*);
从 UI 转换为辅助功能元素,以及UIView* _AXElementForAXUIElementUniqueId(AXUIElementRefGetUniqueID(AXUIElementRef));
在相反的方向。
所有符号均来自AXRuntime.framework
.
在 Mac 中,您需要链接ApplicationServices.framework
并尝试类似的事情。
希望这可以帮助...