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

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


Я пытаюсь написать что-нибудь Автоматизация пользовательского интерфейса для сторонней программы. Я использую Inspect.exe , который поставляется с Windows SDK , и я пробовал как 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);

, я верну правильный элемент. Я могу использовать это как обходной путь, поскольку окно документа - это то, что я действительно хотел в любом случае, но я хотел бы знать, почему панель 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 и начал прогулку с корневой узел.

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

Элемент рабочей области ЕЩЕ нулевой.


Результат найден

Наконец-то я обнаружил 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 ]

27
задан iNet 29 July 2018 в 20:27
поделиться

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 недоступен.

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

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

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

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

23
ответ дан 28 November 2019 в 05:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: