Backend win32 wrappers confuses the "descendants" and "children" methods.
See original GitHub issueExpected Behavior
Using win32, when requesting children of a wrapper, we expend to retrieve the direct descendants of the element. The UIA backend does this right. Note: I need Win32 backend because it’s 1000x faster, and I think I’m trying to control an application that saturates UIA (the delay is 17seconds+ when a batch of this app is working)
Actual Behavior
Every descendant related to the original wrapper is returned.
The following two bugs may be related :
- I tried to filter out those results with
main_window.windows(parent=main_window)and the “parent” filter is not considered. - The “parent” filter does not work in UIA backend.
Steps to Reproduce the Problem
- Have a window with complex descendants tree
- Fetch the dialog using win32 backend
- Try to fetch the Nth child
Short Example of Code to Demonstrate the Problem
Sample code
from pywinauto import Application
# Switch on/of the following lines to compare "UIA" and "Win32" behavior
# app = Application(backend="uia").connect( process=pid )
app = Application(backend="win32").connect( process=pid )
# Another behavior difference between UIA and Win32 with app.top_window() returning my TMainForm (UIA) window or TApplication (Win32) forces me to use this workaround to get the main window. I don't know if TMainForm is supposed to change across different GUI frameworks.
main_win = app.window(class_name="TMainForm", active_only = True).wrapper_object()
def desc( *args ):
print( *args, sep="\n\t", end="\n\n" )
desc( "main_win.descendants()", *main_win.descendants() )
desc( "main_win.children()", *[(x, x.parent()) for x in main_win.children()] )
desc( "main_win.children(parent=main_win)", *[(x, x.parent()) for x in main_win.children(parent=main_win)] )
Results with backend UIA
main_win.descendants() uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - 'Help', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - 'Like us on Facebook', Pane uiawrapper.UIAWrapper - 'Feedback', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - 'About', Pane uiawrapper.UIAWrapper - 'Options', Pane uiawrapper.UIAWrapper - 'Batch Repair', Pane uiawrapper.UIAWrapper - 'Repair', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - 'Start Repair', Pane uiawrapper.UIAWrapper - '...', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - '...', Pane uiawrapper.UIAWrapper - '', Pane uiawrapper.UIAWrapper - 'Repair process log:', Pane uiawrapper.UIAWrapper - 'Save Log', Pane uia_controls.EditWrapper - '', Edit uia_controls.EditWrapper - '', Edit uia_controls.EditWrapper - '', Edit main_win.children() uiawrapper.UIAWrapper - '', Pane ## uiawrapper.UIAWrapper - '', Dialog uiawrapper.UIAWrapper - '', Pane ## uiawrapper.UIAWrapper - '', Dialog uiawrapper.UIAWrapper - '', Pane ## uiawrapper.UIAWrapper - '', Dialog ### Oops, the "parent" filter does not work on UIA backend ### Traceback (most recent call last): File "automate\dwordrecovery.py", line 129, in <module> exit(main()) File "automate\dwordrecovery.py", line 42, in main try_winauto(pid) File "automate\dwordrecovery.py", line 70, in try_winauto desc( "main_win.children()", *[str(x)+" ## "+str(x.parent()) for x in main_win.children(parent=main_win)] ) File "C:\Users\Julien\AppData\Local\Programs\Python\Python38\lib\site-packages\pywinauto\base_wrapper.py", line 470, in children child_elements = self.element_info.children(**kwargs) File "C:\Users\Julien\AppData\Local\Programs\Python\Python38\lib\site-packages\pywinauto\uia_element_info.py", line 282, in children cond = IUIA().build_condition(**kwargs) TypeError: build_condition() got an unexpected keyword argument 'parent'
Results with backend Win32
main_win.descendants() hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.StaticWrapper - '', Static win32_controls.ButtonWrapper - '&Help', Button win32_controls.StaticWrapper - '', Static win32_controls.ButtonWrapper - '&Like us on Facebook', Button win32_controls.ButtonWrapper - '&Feedback', Button hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '', Button win32_controls.ButtonWrapper - '', Button win32_controls.ButtonWrapper - '&About', Button win32_controls.ButtonWrapper - '&Options', Button win32_controls.ButtonWrapper - '&Batch Repair', Button win32_controls.ButtonWrapper - '&Repair', Button hwndwrapper.HwndWrapper - '', TPageControl hwndwrapper.HwndWrapper - '&About', TTabSheet hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - 'License Information:', TbsSkinGroupBox win32_controls.ButtonWrapper - '&Enter License Key', Button win32_controls.ButtonWrapper - 'B&uy Business License for Commercial Use', Button hwndwrapper.HwndWrapper - 'Advanced Options', TTabSheet hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.EditWrapper - '512', Edit win32_controls.ButtonWrapper - '...', Button hwndwrapper.HwndWrapper - '&Batch Repair', TTabSheet hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'Save &Log', Button win32_controls.ButtonWrapper - 'Remo&ve All', Button win32_controls.ButtonWrapper - 'Re&move Files', Button win32_controls.ButtonWrapper - 'S&earch Files', Button win32_controls.ButtonWrapper - 'A&dd Files', Button win32_controls.ButtonWrapper - '&Start Repair', Button hwndwrapper.HwndWrapper - '&Repair', TTabSheet hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'A&dvanced Options', Button win32_controls.ButtonWrapper - 'O&ptions', Button hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TbsSkinGauge win32_controls.StaticWrapper - '', Static win32_controls.ButtonWrapper - '&Start Repair', Button win32_controls.ButtonWrapper - '...', Button win32_controls.ButtonWrapper - '', Button win32_controls.ButtonWrapper - '...', Button hwndwrapper.HwndWrapper - '', TbsSkinScrollBar hwndwrapper.HwndWrapper - 'Repair process log:', TbsSkinLabel win32_controls.ButtonWrapper - 'Save &Log', Button win32_controls.EditWrapper - '', Edit win32_controls.EditWrapper - '', Edit hwndwrapper.HwndWrapper - '', TbsSkinMemo main_win.children() hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.DialogWrapper - '', TMainForm win32_controls.StaticWrapper - '', Static ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Help', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.StaticWrapper - '', Static ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Like us on Facebook', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Feedback', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.DialogWrapper - '', TMainForm hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&About', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Options', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Batch Repair', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Repair', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TPageControl ## hwndwrapper.DialogWrapper - '', TMainForm hwndwrapper.HwndWrapper - '&About', TTabSheet ## hwndwrapper.HwndWrapper - '', TPageControl hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - '&About', TTabSheet hwndwrapper.HwndWrapper - 'License Information:', TbsSkinGroupBox ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Enter License Key', Button ## hwndwrapper.HwndWrapper - 'License Information:', TbsSkinGroupBox win32_controls.ButtonWrapper - 'B&uy Business License for Commercial Use', Button ## hwndwrapper.HwndWrapper - 'License Information:', TbsSkinGroupBox hwndwrapper.HwndWrapper - 'Advanced Options', TTabSheet ## hwndwrapper.HwndWrapper - '', TPageControl hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - 'Advanced Options', TTabSheet win32_controls.EditWrapper - '512', Edit ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '...', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '&Batch Repair', TTabSheet ## hwndwrapper.HwndWrapper - '', TPageControl hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - '&Batch Repair', TTabSheet win32_controls.ButtonWrapper - 'Save &Log', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'Remo&ve All', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'Re&move Files', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'S&earch Files', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'A&dd Files', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Start Repair', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '&Repair', TTabSheet ## hwndwrapper.HwndWrapper - '', TPageControl hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.DialogWrapper - '', TMainForm hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'A&dvanced Options', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'O&ptions', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.DialogWrapper - '', TMainForm hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TbsSkinGauge ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.StaticWrapper - '', Static ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Start Repair', Button ## win32_controls.StaticWrapper - '', Static win32_controls.ButtonWrapper - '...', Button ## win32_controls.StaticWrapper - '', Static win32_controls.ButtonWrapper - '', Button ## win32_controls.StaticWrapper - '', Static win32_controls.ButtonWrapper - '...', Button ## win32_controls.StaticWrapper - '', Static hwndwrapper.HwndWrapper - '', TbsSkinScrollBar ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - 'Repair process log:', TbsSkinLabel ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'Save &Log', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.EditWrapper - '', Edit ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.EditWrapper - '', Edit ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TbsSkinMemo ## hwndwrapper.HwndWrapper - '', TGSFRPanel main_win.children(parent=main_win) hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.DialogWrapper - '', TMainForm win32_controls.StaticWrapper - '', Static ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Help', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.StaticWrapper - '', Static ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Like us on Facebook', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Feedback', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.DialogWrapper - '', TMainForm hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&About', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Options', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Batch Repair', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Repair', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TPageControl ## hwndwrapper.DialogWrapper - '', TMainForm hwndwrapper.HwndWrapper - '&About', TTabSheet ## hwndwrapper.HwndWrapper - '', TPageControl hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - '&About', TTabSheet hwndwrapper.HwndWrapper - 'License Information:', TbsSkinGroupBox ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Enter License Key', Button ## hwndwrapper.HwndWrapper - 'License Information:', TbsSkinGroupBox win32_controls.ButtonWrapper - 'B&uy Business License for Commercial Use', Button ## hwndwrapper.HwndWrapper - 'License Information:', TbsSkinGroupBox hwndwrapper.HwndWrapper - 'Advanced Options', TTabSheet ## hwndwrapper.HwndWrapper - '', TPageControl hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - 'Advanced Options', TTabSheet win32_controls.EditWrapper - '512', Edit ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '...', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '&Batch Repair', TTabSheet ## hwndwrapper.HwndWrapper - '', TPageControl hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - '&Batch Repair', TTabSheet win32_controls.ButtonWrapper - 'Save &Log', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'Remo&ve All', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'Re&move Files', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'S&earch Files', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'A&dd Files', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Start Repair', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '&Repair', TTabSheet ## hwndwrapper.HwndWrapper - '', TPageControl hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.DialogWrapper - '', TMainForm hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'A&dvanced Options', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'O&ptions', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.DialogWrapper - '', TMainForm hwndwrapper.HwndWrapper - '', TGSFRPanel ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TbsSkinGauge ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.StaticWrapper - '', Static ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - '&Start Repair', Button ## win32_controls.StaticWrapper - '', Static win32_controls.ButtonWrapper - '...', Button ## win32_controls.StaticWrapper - '', Static win32_controls.ButtonWrapper - '', Button ## win32_controls.StaticWrapper - '', Static win32_controls.ButtonWrapper - '...', Button ## win32_controls.StaticWrapper - '', Static hwndwrapper.HwndWrapper - '', TbsSkinScrollBar ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - 'Repair process log:', TbsSkinLabel ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.ButtonWrapper - 'Save &Log', Button ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.EditWrapper - '', Edit ## hwndwrapper.HwndWrapper - '', TGSFRPanel win32_controls.EditWrapper - '', Edit ## hwndwrapper.HwndWrapper - '', TGSFRPanel hwndwrapper.HwndWrapper - '', TbsSkinMemo ## hwndwrapper.HwndWrapper - '', TGSFRPanel
Specifications
- Pywinauto version: 0.6.8
- Python version and bitness: 3.8 64bits
- Platform and OS: CMD.exe inside WSL2 inside Windows 10 64bits inside a VM
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (3 by maintainers)
Top Results From Across the Web
pywinauto.base_wrapper — pywinauto 0.6.8 documentation
An element is a direct descendant of a given element if the parent element is the the chain of parent elements for the...
Read more >pywinauto: Iterate through all controls in a window
Correct method to list top-level windows is application.windows() . Then you can call .descendants() for every listed window.
Read more >A system, method and article of manufacture for a legacy ...
A legacy system is interconnected to the client via the integration architecture using a legacy wrapper. The legacy system and the client are...
Read more >Release notes & updates – Azure CLI - Microsoft Learn
az staticwebapp backends link : Link an backend to a static webapp. ... az sql vm update : Add configuration options for SQL...
Read more >Secure Coding in C and C++ - SEI Digital Library
Still others, from the SEI's CERT Program, describe technologies and practices needed to manage software and network security risk. These and all titles...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

I fixed the source code. In the following extract of the file win32_element_info.py, l121
In fact, as one can see in the original function comments, “depth” feature were not implemented. I updated the comment accordingly. Now, as far as I understand this piece of code, I can’t understand the sibling
descendants()function. As it looks like returning the same results.descendants()just seams to includes additional filtering. A discriminating description would be really much appreciated since thechildren()anddescendants()definition is pretty much the same except that “children” has been transposed as “descendants”, letting the user to guess what is named a “child” compared to what is named a “descendant”. I could not clarify that in the Win32 backend, even if the UIA backend is more obvious.Because of this, and because the function is used elsewhere, I did not update the code considering my own definition of a child. We have to indicate “depth” or “parent” argument to retrieve the actual direct children in my update.
Usage example base on my report :
provides the following results :
Those still are not the same results as when using the UIA backend : 3 Panels in UIA, 4 Panels + 1 PageControl in Win32. An explanation would be much appreciated.
Thanks to the developers for their hard work and I hope this patch will help.
Closing as fixed in
atspibranch. It helps us to track progress for 0.7.0 milestone. Thanks for understanding!