AutomationElement apparaît en utilisant Inspect.exe mais ne se présente pas lorsque vous utilisez UIAutomationCore.dll ou système.Windows.Automatisation

TL; DR : Qu'est-ce que je fais de mal qui fait apparaître le volet de l'espace de travail dans les objets Inspect mais pas dans mon code personnalisé?


j'essaie d'écrire un peu D'automatisation D'UI à un programme de tierce partie. J'utilise pour inspecter.exe qui est venu avec le Windows SDK , et j'ai essayé les deux système.Windows.Automatisation et directe com Calls (en utilisant la bibliothèque wrapper de 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);

quand j'essaie le code ci-dessus, parentElement a la référence correcte à la fenêtre du programme principal, mais workspaceElement est null.


Une solution de contournement temporaire:

si je change mon code documentElement en:

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

j'obtiendrai le bon élément retourné. Je peux utiliser ceci comme une solution de contournement car la fenêtre de document est celle que je voulais vraiment de toute façon, mais je voudrais savoir pourquoi la fenêtre de L'espace de travail ne s'est pas montrée afin que je puisse améliorer mes compétences au cas où je tomberais sur ceci dans le futur avec une situation que je ne peux pas contourner.


mise à jour: j'ai essayé les suggestions de 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

j'obtiens 3 résultats, malheureusement, j'ai 4 panneaux, et celui qui ne s'est pas présenté a été le panneau nommé Workspace .

j'ai aussi essayé d'utiliser un 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);

mais qui renvoie aussi null pour workspaceElement

finalement, en désespoir de cause, j'ai essayé la valeur actuelle de "NativeWindowHandle" de Inspect et j'ai commencé à marcher à partir du noeud racine.

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

espace de travail l'élément est STILL null.


Résultat Trouvé

j'ai finalement réussi à trouver de l'espace de travail, mais j'ai dû jouer

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

et il a fallu beaucoup de temps pour courir.

Vieilles Captures D'Écran

Voici des captures d'écran de Inspect.exe montrant l'arborescence.

enter image description here

Voici les propriétés de la fenêtre principale du programme.

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)RedactedProgramFiles7RedactedClientFolder"
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 ]

Voici les propriétés du problème" 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 ]

Voici les propriétés de la fenêtre du document" Working".

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 ]
26
demandé sur iPython 2012-02-14 22:34:54

1 réponses

très belle question. Basé sur le problème que vous avez documenté, il est clair que votre conditionnel:

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

... échec de l'évaluation. Pourquoi?

la réponse est comment votre conditionnel est évalué. En regardant votre arbre d'éléments, nous remarquons cette propriété pour Workspace :

IsWindowPatternAvailable:   false

Et pour la fenêtre principale et Untitled3 :

IsWindowPatternAvailable:   true

de MSDN :

UIA_IsWindowPatternAvailablePropertyId 30044

identifie la propriété IsWindowPatternAvailable , qui indique si le modèle de contrôle de fenêtre est disponible pour l'élément d'automatisation. Si TRUE , un client peut récupérer une interface IUIAutomationWindowPattern de l'élément.

nous trouvons un repro dans ce thread , qui implique le même schéma de défaillance que celui que vous êtes actuellement l'expérience. Nous notons également l'absence de propriétés Window présentes pour cet élément car IUIAutomationWindowPattern est inaccessible.

une solution de contournement est disponible à partir du thread précédent . Au lieu de PropertyCondition , on pourrait utiliser:

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

ou, alternativement, on pourrait utiliser le contournement que vous avez donné, à condition que votre structure d'arbre est garantie d'être peu profonde (et donc, approprié au nom de ce site, sera ne pas déclencher un débordement de pile).

Certes, ce n'était pas le problème le plus évident. Dans le monde parfait, MSDN devrait ont une meilleure documentation sur ce sujet.

23
répondu MrGomez 2017-05-23 12:26:00