import Cocoa let app = AXUIElementCreateApplication(1668) func attr(_ e: AXUIElement, _ name: String) -> CFTypeRef? { var v: CFTypeRef? return AXUIElementCopyAttributeValue(e, name as CFString, &v) == .success ? v : nil } func frame(_ e: AXUIElement) -> String { var p = CGPoint.zero, s = CGSize.zero if let pv = attr(e, kAXPositionAttribute), let sv = attr(e, kAXSizeAttribute) { AXValueGetValue(pv as! AXValue, .cgPoint, &p) AXValueGetValue(sv as! AXValue, .cgSize, &s) return String(format: "(%.0f,%.0f %.0fx%.0f)", p.x, p.y, s.width, s.height) } return "?" } func str(_ e: AXUIElement, _ a: String) -> String { if let v = attr(e, a) as? String { return v.replacingOccurrences(of: "\n", with: " ") } return "" } var found = 0 func walk(_ e: AXUIElement, _ depth: Int) { if found > 40 { return } let t = str(e, kAXTitleAttribute), v = str(e, kAXValueAttribute), d = str(e, kAXDescriptionAttribute) let all = t + v + d if all.contains("批准") || all.contains("拒绝") || all.contains("待审批") || all.contains("画中画") || all.contains("HoloLake") { print("[HIT d\(depth)] role=\(str(e,kAXRoleAttribute)) title='\(String(t.prefix(60)))' val='\(String(v.prefix(60)))' desc='\(String(d.prefix(60)))' frame=\(frame(e))") found += 1 } if let kidsAny = attr(e, kAXChildrenAttribute) as? [AnyObject] { let kids = kidsAny.map { $0 as! AXUIElement } for k in kids { walk(k, depth+1) } } } if let wins = attr(app, kAXWindowsAttribute) as? [AXUIElement] { print("windowCount=\(wins.count)") for (i,w) in wins.enumerated() { print("win[\(i)] title='\(str(w,kAXTitleAttribute))' frame=\(frame(w))") walk(w, 0) } } if let f0 = attr(app, kAXFocusedUIElementAttribute) { let f = f0 as! AXUIElement print("FOCUSED role=\(str(f,kAXRoleAttribute)) frame=\(frame(f)) desc='\(String(str(f,kAXDescriptionAttribute).prefix(40)))'") }