AutomationElement使用Inspect.exe显示,但在使用UIAutomationCore.dll或System.Windows.Automation时不显示

TL; DR :我做错了导致工作区窗格显示在Inspect Objects中但未显示在我的自定义代码中?


我正在尝试为第三方程序编写一些UI自动化。 我正在使用Windows SDK附带的Inspect.exe ,我已经尝试过System.Windows.Automation和直接COM调用 (使用来自UIA Verify的包装器库)。

Process[] processes = Process.GetProcessesByName("Redacted Client"); if (processes.Length == 0) throw new Exception("Could not find \"Redacted Client\" process"); PropertyCondition parentFileCond = new PropertyCondition(AutomationElement.ProcessIdProperty, processes[0].Id); PropertyCondition workspaceCond = new PropertyCondition(AutomationElement.NameProperty, "Workspace", PropertyConditionFlags.IgnoreCase); PropertyCondition documentCond = new PropertyCondition(AutomationElement.NameProperty, "Untitled3", PropertyConditionFlags.IgnoreCase); var parentElement = AutomationElement.RootElement.FindFirst(TreeScope.Children, parentFileCond); var workspaceElement = parentElement.FindFirst(TreeScope.Children, workspaceCond); //Also does not work with TreeScope.Descendants var documentElement = workspaceElement.FindFirst(TreeScope.Children, documentCond); 

当我尝试上面的代码时, parentElement确实有对主程序窗口的正确引用,但workspaceElement为null。


临时解决方法:

如果我将documentElement代码更改为:

 var documentElement = parentElement.FindFirst(TreeScope.Descendants, documentCond); 

我会得到正确的元素返回。 我可以使用它作为一种解决方法,因为文档窗口是我真正想要的那个,但我想知道为什么工作区窗格不会显示,所以我可以提高我的技能,以防我将来遇到这个问题。我无法解决的情况。


更新:我试过MrGomez的建议

 PropertyCondition parentFileCond = new PropertyCondition(AutomationElement.ProcessIdProperty, 5872); PropertyCondition panelCond = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Pane); var parentElement = AutomationElement.RootElement.FindFirst(TreeScope.Children, parentFileCond); var panels = parentElement.FindAll(TreeScope.Children, panelCond); 

在此处输入图像描述

我得到了3个结果,不幸的是,我有4个面板,而没有出现的那个是名为Workspace的面板。

我也试过使用TreeWalker

 PropertyCondition parentFileCond = new PropertyCondition(AutomationElement.ProcessIdProperty, 5872); PropertyCondition workspaceCond= new PropertyCondition(AutomationElement.NameProperty, "Workspace"); var walker = new TreeWalker(workspaceCond); var parentElement = AutomationElement.RootElement.FindFirst(TreeScope.Children, parentFileCond); var workspaceElement = walker.Normalize(parentElement); 

但是对于workspaceElement也返回null

最后,在绝望中,我尝试了Inspect的“NativeWindowHandle”的当前值,并从根节点开始步行。

 PropertyCondition workspaceCond = new PropertyCondition(AutomationElement.NativeWindowHandleProperty, 0x110906); var walker = new TreeWalker(workspaceCond); var workspaceElement = walker.Normalize(AutomationElement.RootElement); 

Workspace元素仍为STILL null。


找到结果

我终于让Workspace出现了,但我不得不表演

 PropertyCondition workspaceCond = new PropertyCondition(AutomationElement.NativeWindowHandleProperty, 0x110906); var test = AutomationElement.RootElement.FindFirst(TreeScope.Subtree, workspaceCond); 

跑了很长一段时间。

旧屏幕捕获

以下是来自Inspect.exe的屏幕截图,显示了树视图。

在此处输入图像描述

以下是程序主窗口的属性。

 How found: Selected from tree... RuntimeId: "[42.2557552]" BoundingRectangle: {l:75 t:1 r:1311 b:1003} ProcessId: 8160 ControlType: UIA_WindowControlTypeId (0xC370) LocalizedControlType: "window" Name: "Redacted" AccessKey: "" HasKeyboardFocus: false IsKeyboardFocusable: true IsEnabled: true ClassName: "C:\Program Files (x86)\RedactedProgramFiles7\RedactedClientFolder" HelpText: "" IsPassword: false NativeWindowHandle: 0x270670 IsOffscreen: false FrameworkId: "Win32" ProviderDescription: "[pid:4000,hwnd:0x270670 Main:Nested [pid:8160,hwnd:0x270670 Annotation(parent link):Microsoft: Annotation Proxy (unmanaged:uiautomationcore.dll); Main:Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll)]; Nonclient:Microsoft: Non-Client Proxy (unmanaged:uiautomationcore.dll); Hwnd(parent link):Microsoft: HWND Proxy (unmanaged:uiautomationcore.dll)]" Window.CanMaximize: true Window.CanMinimize: true Window.WindowVisualState: Normal (0) Window.WindowInteractionState: ReadyForUserInteraction (2) Window.IsModal: false Window.IsTopmost: false Transform.CanMove: true Transform.CanResize: true Transform.CanRotate: false LegacyIAccessible.ChildId: 0 LegacyIAccessible.DefaultAction: "" LegacyIAccessible.Description: "" LegacyIAccessible.Help: "" LegacyIAccessible.KeyboardShortcut: "" LegacyIAccessible.Name: "Redacted" LegacyIAccessible.Role: client (0xA) LegacyIAccessible.State: focusable (0x100000) LegacyIAccessible.Value: "" IsDockPatternAvailable: false IsExpandCollapsePatternAvailable: false IsGridItemPatternAvailable: false IsGridPatternAvailable: false IsInvokePatternAvailable: false IsLegacyIAccessiblePatternAvailable: true IsMultipleViewPatternAvailable: false IsRangeValuePatternAvailable: false IsScrollPatternAvailable: false IsScrollItemPatternAvailable: false IsSelectionItemPatternAvailable: false IsSelectionPatternAvailable: false IsTablePatternAvailable: false IsTableItemPatternAvailable: false IsTextPatternAvailable: false IsTogglePatternAvailable: false IsTransformPatternAvailable: true IsValuePatternAvailable: false IsWindowPatternAvailable: true IsItemContainerPatternAvailable: false IsVirtualizedItemPatternAvailable: false IsSynchronizedInputPatternAvailable: false FirstChild: "Workspace" pane LastChild: "Application" menu bar Next: "Inspect (HWND: 0x01700F06)" window Previous: "Sandbox Console (Debugging) - Microsoft Visual Studio (Administrator)" window Other Props: Object has no additional properties Children: "Workspace" pane (null) title bar "Application" menu bar Ancestors: "Desktop" pane [ No Parent ] 

以下是问题“工作区”窗格的属性。

 How found: Selected from tree... RuntimeId: "[42.34146524]" BoundingRectangle: {l:83 t:51 r:1303 b:995} ProcessId: 8160 ControlType: UIA_PaneControlTypeId (0xC371) LocalizedControlType: "pane" Name: "Workspace" AccessKey: "" HasKeyboardFocus: false IsKeyboardFocusable: true IsEnabled: true ClassName: "MDIClient" HelpText: "" IsPassword: false NativeWindowHandle: 0x20908DC IsOffscreen: false FrameworkId: "Win32" ProviderDescription: "[pid:4000,hwnd:0x20908DC Main:Nested [pid:8160,hwnd:0x20908DC Annotation(parent link):Microsoft: Annotation Proxy (unmanaged:uiautomationcore.dll); Main:Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll)]; Hwnd(parent link):Microsoft: HWND Proxy (unmanaged:uiautomationcore.dll)]" LegacyIAccessible.ChildId: 0 LegacyIAccessible.DefaultAction: "" LegacyIAccessible.Description: "" LegacyIAccessible.Help: "" LegacyIAccessible.KeyboardShortcut: "" LegacyIAccessible.Name: "Workspace" LegacyIAccessible.Role: client (0xA) LegacyIAccessible.State: focusable (0x100000) LegacyIAccessible.Value: "" IsDockPatternAvailable: false IsExpandCollapsePatternAvailable: false IsGridItemPatternAvailable: false IsGridPatternAvailable: false IsInvokePatternAvailable: false IsLegacyIAccessiblePatternAvailable: true IsMultipleViewPatternAvailable: false IsRangeValuePatternAvailable: false IsScrollPatternAvailable: false IsScrollItemPatternAvailable: false IsSelectionItemPatternAvailable: false IsSelectionPatternAvailable: false IsTablePatternAvailable: false IsTableItemPatternAvailable: false IsTextPatternAvailable: false IsTogglePatternAvailable: false IsTransformPatternAvailable: false IsValuePatternAvailable: false IsWindowPatternAvailable: false IsItemContainerPatternAvailable: false IsVirtualizedItemPatternAvailable: false IsSynchronizedInputPatternAvailable: false FirstChild: "Untitled3" window LastChild: "Letters (32638 of 32638):" window Next: (null) title bar Previous: [null] Other Props: Object has no additional properties Children: "Untitled3" window "Letters (32638 of 32638):" window Ancestors: "Redacted" window "Desktop" pane [ No Parent ] 

以下是“工作”文档窗口的属性。

 How found: Selected from tree... RuntimeId: "[42.9505096]" BoundingRectangle: {l:85 t:53 r:651 b:491} ProcessId: 8160 ControlType: UIA_WindowControlTypeId (0xC370) LocalizedControlType: "window" Name: "Untitled3" AccessKey: "" HasKeyboardFocus: false IsKeyboardFocusable: true IsEnabled: true AutomationId: "10" ClassName: "ProToolsSubMDIWndClass" HelpText: "" IsPassword: false NativeWindowHandle: 0x910948 IsOffscreen: false FrameworkId: "Win32" ProviderDescription: "[pid:4000,hwnd:0x910948 Main:Nested [pid:8160,hwnd:0x910948 Annotation(parent link):Microsoft: Annotation Proxy (unmanaged:uiautomationcore.dll); Main:Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll)]; Nonclient:Microsoft: Non-Client Proxy (unmanaged:uiautomationcore.dll); Hwnd(parent link):Microsoft: HWND Proxy (unmanaged:uiautomationcore.dll)]" Window.CanMaximize: true Window.CanMinimize: true Window.WindowVisualState: Normal (0) Window.WindowInteractionState: ReadyForUserInteraction (2) Window.IsModal: false Window.IsTopmost: false Transform.CanMove: true Transform.CanResize: true Transform.CanRotate: false LegacyIAccessible.ChildId: 0 LegacyIAccessible.DefaultAction: "" LegacyIAccessible.Description: "" LegacyIAccessible.Help: "" LegacyIAccessible.KeyboardShortcut: "" LegacyIAccessible.Name: "Untitled3" LegacyIAccessible.Role: client (0xA) LegacyIAccessible.State: focusable (0x100000) LegacyIAccessible.Value: "" IsDockPatternAvailable: false IsExpandCollapsePatternAvailable: false IsGridItemPatternAvailable: false IsGridPatternAvailable: false IsInvokePatternAvailable: false IsLegacyIAccessiblePatternAvailable: true IsMultipleViewPatternAvailable: false IsRangeValuePatternAvailable: false IsScrollPatternAvailable: false IsScrollItemPatternAvailable: false IsSelectionItemPatternAvailable: false IsSelectionPatternAvailable: false IsTablePatternAvailable: false IsTableItemPatternAvailable: false IsTextPatternAvailable: false IsTogglePatternAvailable: false IsTransformPatternAvailable: true IsValuePatternAvailable: false IsWindowPatternAvailable: true IsItemContainerPatternAvailable: false IsVirtualizedItemPatternAvailable: false IsSynchronizedInputPatternAvailable: false FirstChild: "" thumb LastChild: (null) title bar Next: "Letters (32638 of 32638):" window Previous: [null] Other Props: Object has no additional properties Children: "" thumb (null) title bar Ancestors: "Workspace" pane "Redacted" window "Desktop" pane [ No Parent ] 

非常好的问题。 根据您记录的问题,很明显您的条件:

 PropertyCondition workspaceCond = new PropertyCondition( AutomationElement.NameProperty, "Workspace", PropertyConditionFlags.IgnoreCase); 

……评估失败。 为什么?

答案是如何评估条件。 查看元素树,我们注意到Workspace这个属性:

 IsWindowPatternAvailable: false 

对于主窗口和Untitled3

 IsWindowPatternAvailable: true 

来自MSDN :

 UIA_IsWindowPatternAvailablePropertyId 30044 

标识IsWindowPatternAvailable属性,该属性指示Window控件模式是否可用于自动化元素。 如果为TRUE ,则客户端可以从元素中检索IUIAutomationWindowPattern接口。

我们在这个post中找到了一个repro,它暗示了与你当前遇到的故障模式相同的故障模式。 我们还注意到该元素缺少Window属性,因为IUIAutomationWindowPattern不可访问。

可以从前面提到的线程获得解决方法。 可以使用以下方法代替PropertyCondition

 public class ConditionMatcher : IMatchConditions { public bool Matches(AutomationElement element, Condition condition) { return new TreeWalker(condition).Normalize(element) != null; } } 

或者,也可以使用您给出的变通方法,前提是您的树结构保证浅(因此,适合此站点的名称,不会触发堆栈溢出)。

不可否认,这不是最明显的问题。 在完美的世界中,MSDN 应该有更好的文档来讨论这个主题。