如何通过UI Automation获取指定窗口的标题栏?
解决UIAutomation无法获取CMD窗口标题栏的问题
问题根源
你当前的代码存在两个核心问题:
- 搜索范围太窄:使用
"Children"仅搜索窗口的直接子元素,但标题栏通常位于窗口控件树的更深层级,属于后代元素而非直接子元素。 - 窗口定位方式效率低:通过
FindAll遍历所有根元素再筛选的方式不仅低效,还可能因窗口名称匹配问题导致获取到错误的元素。
修正后的代码
Add-Type -AssemblyName 'UIAutomationClient' # 定义控件树搜索范围常量 $treeScopeDescendants = [System.Windows.Automation.TreeScope]::Descendants # 1. 精准定位CMD窗口 $windowNameCond = [System.Windows.Automation.PropertyCondition]::new( [System.Windows.Automation.AutomationElement]::NameProperty, 'Command Prompt' ) $windowTypeCond = [System.Windows.Automation.PropertyCondition]::new( [System.Windows.Automation.AutomationElement]::ControlTypeProperty, [System.Windows.Automation.ControlType]::Window ) $cmdWindowCond = [System.Windows.Automation.AndCondition]::new($windowNameCond, $windowTypeCond) $cmdWindow = [Windows.Automation.AutomationElement]::RootElement.FindFirst($treeScopeDescendants, $cmdWindowCond) if (-not $cmdWindow) { Write-Host "未找到CMD窗口" exit } # 2. 搜索标题栏(遍历所有后代元素) $titleBarCond = [System.Windows.Automation.PropertyCondition]::new( [System.Windows.Automation.AutomationElement]::ControlTypeProperty, [System.Windows.Automation.ControlType]::TitleBar ) $titleBar = $cmdWindow.FindFirst($treeScopeDescendants, $titleBarCond) # 输出结果 if ($titleBar) { Write-Host "找到标题栏:" $titleBar.Current.Name } else { Write-Host "未找到标题栏" }
关键修改说明
- 扩大搜索范围:将搜索标题栏的范围从
Children改为Descendants,确保遍历窗口控件树的所有层级。 - 精准定位窗口:结合窗口名称和控件类型的条件查找CMD窗口,避免误匹配其他同名元素。
- 增加错误判断:添加窗口不存在的判断逻辑,避免后续代码无意义执行。
额外提示
如果仍无法找到标题栏,可能是系统或窗口的UI自动化结构差异导致:
- 可以使用系统自带的Inspect.exe工具查看CMD窗口的控件树结构,确认标题栏的实际控件类型和位置。
- 部分窗口的标题栏可能被标记为
Custom控件类型,需要结合AutomationId等其他属性来定位。
内容的提问来源于stack exchange,提问作者Carsten
相关产品推荐
相关产品推荐

