Подтвердить что ты не робот

AutomationElement отображается с помощью Inspect.exe, но не отображается при использовании UIAutomationCore.dll или System.Windows.Automation

TL; DR: что я делаю неправильно, из-за чего область рабочего пространства появляется в Inspect Objects, но не отображается в моем пользовательском коде?


Я пытаюсь написать некоторую автоматизацию пользовательского интерфейса для сторонней программы. Я использую Inspect.exe, который поставляется с Windows SDK, и я попробовал как System.Windows.Automation и direct COM-вызовы (используя библиотеку обертки из Проверка UIA).

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);

Я верну правильный элемент. Я могу использовать это как обходной путь, так как окно документа - это то, что я действительно хотел в любом случае, но я хотел бы знать, почему панель Workspace не появляется, поэтому я могу улучшить свои навыки, если я буду работать с этим в будущем, ситуация, с которой я не могу работать.


ОБНОВЛЕНИЕ: Я пробовал предложения 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);

enter image description here

Я получаю 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);

но также возвращает null для workspaceElement

Наконец, в отчаянии я попробовал текущее значение "NativeWindowHandle" от Inspect и начал ходить от корня node.

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

Элемент рабочей области STILL null.


Найдено результат

Я наконец-то получил Workspace, чтобы показать, но мне пришлось выполнить

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

и для запуска потребовалось довольно много времени.

Старые снимки экрана

Вот скриншот из Inspect.exe, показывающий древовидное представление.

enter image description here

Вот основные свойства программы.

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 ]
4b9b3361

Ответ 1

Очень хороший вопрос. Основываясь на проблеме, которую вы задокументировали, ясно, что ваш условный:

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

... не выполняется оценка. Почему?

Ответ заключается в том, как оценивается ваше условное выражение. Посмотрев на ваше дерево элементов, мы замечаем это свойство для Workspace:

IsWindowPatternAvailable:   false

И для главного окна и Untitled3:

IsWindowPatternAvailable:   true

Из MSDN:

UIA_IsWindowPatternAvailablePropertyId 30044

Определяет свойство IsWindowPatternAvailable, которое указывает, доступен ли шаблон управления Window для элемента автоматизации. Если TRUE, клиент может извлечь из элемента IUIAutomationWindowPattern.

В этом потоке мы находим репрограмму , которая подразумевает тот же шаблон сбоя, что и тот, который вы сейчас испытываете. Мы также отмечаем отсутствие свойств Window для этого элемента, поскольку IUIAutomationWindowPattern недоступен.

Обходной путь доступен из aforledink thread. Вместо PropertyCondition можно использовать:

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

Или, альтернативно, можно использовать обходной путь, который вы указали, если ваша древовидная структура гарантирована быть мелкой (и, следовательно, соответствует названию этого сайта, не приведет к переполнению стека).

По общему признанию, это была не самая очевидная проблема. В идеальном мире MSDN должна иметь лучшую документацию по этой теме.