C# AutomationElement 使用 Inspect.exe 显示,但在使用 UIAutomationCore.dll 或 System.Windows.Automation 时不显示
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9282275/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AutomationElement shows up using Inspect.exe but does show not up when using UIAutomationCore.dll or System.Windows.Automation
提问by Scott Chamberlain
TL;DR: What am I doing wrong that is causing the workspace pane to show up in Inspect Objects but not show up in my custom code?
TL;DR:我做错了什么导致工作区窗格显示在检查对象中但没有显示在我的自定义代码中?
I am trying to write some UI automation to a 3rd party program. I am using Inspect.exethat came with the Windows SDK, and I have tried both System.Windows.Automationand direct COM Calls(using the wrapper library from UIA Verify).
我正在尝试为 3rd 方程序编写一些 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);
When I try the above code, parentElementdoes have the correct reference to the main program window, but workspaceElementis null.
当我尝试上面的代码时,parentElement确实对主程序窗口有正确的引用,但workspaceElement为空。
A temporary workaround:
临时解决办法:
If I change my documentElementcode to:
如果我将documentElement代码更改为:
var documentElement = parentElement.FindFirst(TreeScope.Descendants, documentCond);
I will get the correct element returned. I can use this as a workaround as the document window is the one I really wanted anyway, but I would like to know why the Workspace pane would not show up so I can improve my skills in case I run into this in the future with a situation I cannot work around.
我会得到正确的元素返回。我可以使用它作为一种解决方法,因为文档窗口无论如何都是我真正想要的,但我想知道为什么工作区窗格不会显示,以便我可以提高我的技能,以防我将来遇到这种情况我无法解决的情况。
UPDATE: I tried MrGomez's suggestions
更新:我尝试了戈麦斯先生的建议
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);


I get 3 results, unfortunately, I have 4 panels, and the one that did not show up was the panel named Workspace.
我得到了 3 个结果,不幸的是,我有 4 个面板,没有出现的是名为Workspace.
I also tried to use a TreeWalker
我也尝试使用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);
but that also returns null for workspaceElement
但这也为 workspaceElement
Finally, in desperation, I tried the current value of "NativeWindowHandle" from Inspect and started the walking from the root node.
最后,无奈之下,我从Inspect中尝试了“NativeWindowHandle”的当前值,并从根节点开始了行走。
PropertyCondition workspaceCond = new PropertyCondition(AutomationElement.NativeWindowHandleProperty, 0x110906);
var walker = new TreeWalker(workspaceCond);
var workspaceElement = walker.Normalize(AutomationElement.RootElement);
Workspace element is STILLnull.
工作区元素仍然为空。
Result Found
找到结果
I finally did get Workspace to show up, but I had to perform
我终于让 Workspace 出现了,但我必须表演
PropertyCondition workspaceCond = new PropertyCondition(AutomationElement.NativeWindowHandleProperty, 0x110906);
var test = AutomationElement.RootElement.FindFirst(TreeScope.Subtree, workspaceCond);
and it took quite a while to run.
并且跑了好久。
Old Screen Captures
旧屏幕截图
Here is screenshots from Inspect.exe showing the tree view.
这是 Inspect.exe 中显示树视图的屏幕截图。


Here are the properties of the main window of the program.
以下是程序主窗口的属性。
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 ]
Here are the properties of the problem "Workspace" pane.
以下是问题“工作区”窗格的属性。
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 ]
Here are the properties of the "Working" document window.
以下是“工作”文档窗口的属性。
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 ]
采纳答案by MrGomez
Very nice question. Based upon the problem you've documented, it's clear that your conditional:
非常好的问题。根据您记录的问题,很明显您的条件是:
PropertyCondition workspaceCond = new PropertyCondition(
AutomationElement.NameProperty, "Workspace", PropertyConditionFlags.IgnoreCase);
... fails evaluation. Why?
... 评估失败。为什么?
The answer is how your conditional is evaluated. Looking at your element tree, we notice this property for Workspace:
答案是如何评估您的条件。查看您的元素树,我们注意到以下属性Workspace:
IsWindowPatternAvailable: false
And for the main window and Untitled3:
对于主窗口和Untitled3:
IsWindowPatternAvailable: true
UIA_IsWindowPatternAvailablePropertyId 30044Identifies the
IsWindowPatternAvailableproperty, which indicates whether the Window control pattern is available for the automation element. IfTRUE, a client can retrieve anIUIAutomationWindowPatterninterface from the element.
UIA_IsWindowPatternAvailablePropertyId 30044标识
IsWindowPatternAvailable属性,该属性指示 Window 控件模式是否可用于自动化元素。如果TRUE,客户端可以IUIAutomationWindowPattern从元素中检索接口。
We find a repro in this thread, which implies the same failure pattern as the one you are currently experiencing. We also note the lack of Windowproperties present for this element because IUIAutomationWindowPatternis inaccessible.
我们在此线程中找到了一个重现,这意味着与您当前遇到的故障模式相同。我们还注意到Window该元素缺少属性,因为IUIAutomationWindowPattern无法访问。
A workaround is available from the aforelinked thread. Instead of PropertyCondition, one might use:
可以从上述线程获得解决方法。而不是PropertyCondition,可以使用:
public class ConditionMatcher : IMatchConditions
{
public bool Matches(AutomationElement element, Condition condition)
{
return new TreeWalker(condition).Normalize(element) != null;
}
}
Or, alternately, one might use the workaround you've given, provided your tree structure is guaranteed to be shallow (and thus, appropriate to the name of this site, will not trigger a stack overflow).
或者,也可以使用您提供的解决方法,前提是您的树结构保证是浅的(因此,适合该站点的名称,不会触发堆栈溢出)。
Admittedly, this wasn't the most obvious issue. In the perfect world, MSDN shouldhave better documentation on this topic.
诚然,这并不是最明显的问题。在完美的世界中,MSDN应该有关于这个主题的更好的文档。

