如何通过C#的UI Automation获取第三方应用工具栏中的按钮?
解决UIAutomation无法访问工具栏按钮的问题
很多第三方应用的工具栏控件不会直接将按钮作为标准AutomationElement后代暴露,以下是几个可行的解决方向:
1. 调整查找条件与范围,结合ControlType筛选
不要仅依赖NameProperty,搭配ControlType定位工具栏按钮(通常为ControlType.Button),同时调整查找范围:
// 使用TreeScope.Subtree遍历工具栏所有层级,结合按钮类型与启用状态筛选 var toolbarButtons = _toolbarElement.FindAll(TreeScope.Subtree, new AndCondition( new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button), new PropertyCondition(AutomationElement.IsEnabledProperty, true) )); if (toolbarButtons.Count > 0) { var targetButton = toolbarButtons[0]; // 通过InvokePattern执行点击 if (targetButton.TryGetCurrentPattern(InvokePattern.Pattern, out var patternObj)) { var invokePattern = (InvokePattern)patternObj; invokePattern.Invoke(); } }
2. 用RawViewWalker遍历底层控件树
默认TreeWalker会过滤部分"不可见"自动化元素,改用RawViewWalker可获取更完整的控件结构:
TreeWalker rawWalker = TreeWalker.RawViewWalker; AutomationElement currentElement = rawWalker.GetFirstChild(_toolbarElement); while (currentElement != null) { if ((ControlType)currentElement.GetCurrentPropertyValue(AutomationElement.ControlTypeProperty) == ControlType.Button) { if (currentElement.TryGetCurrentPattern(InvokePattern.Pattern, out var pattern)) { ((InvokePattern)pattern).Invoke(); break; } } currentElement = rawWalker.GetNextSibling(currentElement); }
3. 针对Win32原生工具栏的特殊处理
如果目标是Win32原生工具栏(类名ToolbarWindow32),UIAutomation可能无法直接识别按钮,可结合Windows API操作:
// 获取工具栏原生句柄 IntPtr toolbarHandle = (IntPtr)_toolbarElement.GetCurrentPropertyValue(AutomationElement.NativeWindowHandleProperty); // 调用Win32 API获取按钮数量 int buttonCount = SendMessage(toolbarHandle, TB_BUTTONCOUNT, 0, 0); for (int i = 0; i < buttonCount; i++) { // 发送点击指令到指定按钮 SendMessage(toolbarHandle, TB_COMMANDCLICK, (IntPtr)i, 0); } // 导入所需Win32 API [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); private const uint TB_BUTTONCOUNT = 0x0418; private const uint TB_COMMANDCLICK = 0x0450;
4. 用工具验证控件结构
使用Windows SDK自带的Inspect.exe查看目标工具栏的自动化结构,确认按钮的真实属性(如Name、AutomationId、ControlType),以此编写更精准的查找条件。
内容的提问来源于stack exchange,提问作者Dan
相关产品推荐
相关产品推荐

