[PYTHON] Notes on how to use pywinauto

Notes on how to use pywinauto

Check the operation with Notepad

Launch the app (Notepad)

c:\ python
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 
>>> from pywinauto import Desktop, Application
>>>
>>> #Launch Notepad
>>> app = Application().start('notepad.exe')

Display version information

Select "Version Information" from "Help" in the menu to display the version information screen.

>>> #help->Display version information
>>> app[u"Untitled notepad"].menu_select(u"help->version information")

notepad2.png

Confirmation of existence of version information screen

>>> print ( app[u"Notepad version information"].exists() )
True
>>>

Get control information of version information screen

>>> window = app.top_window()
>>> window.print_control_identifiers()
Control Identifiers:

Dialog - 'Notepad version information'    (L690, T232, R1240, B711)
['Notepad version information', 'Dialog', 'Notepad version informationDialog']
child_window(title="Notepad version information", class_name="#32770")
   |
   | Static - ''    (L716, T348, R1213, B350)
   | ['Notepad version information Static', 'Static', 'Notepad version information Static0', 'Notepad version information Static1', 'Static0', 'Static1']
   | child_window(class_name="Static")
   |
   | Static - ''    (L710, T367, R747, B405)
   | ['Notepad version information Static2', 'Static2']
   | child_window(class_name="Static")
   |
   | Static - 'Microsoft Windows'    (L759, T367, R1162, B386)
   | ['Static3', 'Microsoft WindowsStatic', 'Microsoft Windows']
   | child_window(title="Microsoft Windows", class_name="Static")
   |
   | Static - 'Version 1809(OS build 17763.1397)'    (L759, T386, R1223, B405)
   | ['Version 1809(OS build 17763.1397)', 'Static4', 'Version 1809(OS build 17763.1397)Static']
   | child_window(title="Version 1809(OS build 17763.1397)", class_name="Static")
   |
   | Static - '© 2018 Microsoft Corporation. All rights reserved.'    (L759, T404, R1179, B423)
   | ['© 2018 Microsoft Corporation. All rights reserved.Static', '© 2018 Microsoft Corporation. All rights reserved.', 'Static5', '© 2018 Microsoft Corporation. All rights reserved.Static0', '© 2018 Microsoft Corporation. All rights reserved.Static1']
   | child_window(title="© 2018 Microsoft Corporation. All rights reserved.", class_name="Static")
   |
   | Static - ''    (L759, T423, R1179, B442)
   | ['© 2018 Microsoft Corporation. All rights reserved.Static2', 'Static6']
   | child_window(class_name="Static")
   |
   | Static - 'Windows 10 Enterprise operating system and user interface in the US and other countries/Protected by local trademarks and other intellectual property rights.'    (L759, T442, R1179, B517)
   | ['Static7', 'Windows 10 Enterprise operating system and user interface in the US and other countries/Protected by local trademarks and other intellectual property rights.', 'Windows 10 Enterprise operating system and user interface in the US and other countries/Protected by local trademarks and other intellectual property rights. Static', 'Windows 10 Enterprise operating system and user interface in the US and other countries/Protected by local trademarks and other intellectual property rights. Static0', 'Windows 10 Enterprise operating system and user interface in the US and other countries/Protected by local trademarks and other intellectual property rights. Static1']
   | child_window(title="Windows 10 Enterprise operating system and user interface in the US and other countries/Protected by local trademarks and other intellectual property rights.", class_name="Static")
   |
   | Static - ''    (L759, T517, R1127, B555)
   | ['Static8', 'Windows 10 Enterprise operating system and user interface in the US and other countries/Protected by local trademarks and other intellectual property rights. Static2']
   | child_window(class_name="Static")
   |
   | SysLink - 'This product is<A>Microsoft Software License Terms</A>It is licensed to the following people based on the conditions of.'    (L759, T554, R1127, B592)
   | ['This product is<A>Microsoft Software License Terms</A>It is licensed to the following people based on the conditions of.', 'This product is<A>Microsoft Software License Terms</A>It is licensed to the following people based on the conditions of.SysLink', 'SysLink']
   | child_window(title="This product is<A>Microsoft Software License Terms</A>It is licensed to the following people based on the conditions of.", class_name="SysLink")
   |
   | Static - 'Windows users'    (L777, T592, R1145, B611)
   | ['Windows user Static', 'Static9', 'Windows users', 'Windows user Static0', 'Windows user Static1']
   | child_window(title="Windows users", class_name="Static")
   |
   | Static - ''    (L777, T611, R1145, B630)
   | ['Windows user Static2', 'Static10']
   | child_window(class_name="Static")
   |
   | Button - 'OK'    (L1136, T665, R1224, B691)
   | ['OKButton', 'OK', 'Button']
   | child_window(title="OK", class_name="Button")
>>>

Close the version information screen

Press the OK button to close the version information screen

>>> app[u"Notepad version information"].OK.close_click()
<win32_controls.ButtonWrapper - '', Button, 462076>
>>>

Display notepad control information

>>> app[u"Untitled notepad"].dump_tree()
Control Identifiers:

Notepad - 'Untitled-Notepad'    (L673, T177, R1770, B798)
['Untitled-Notepad', 'Notepad', 'Untitled-NotepadNotepad']
child_window(title="Untitled-Notepad", class_name="Notepad")
   |
   | Edit - ''    (L681, T228, R1762, B766)
   | ['Edit', 'Untitled-Notepad Edit']
   | child_window(class_name="Edit")
   |
   | StatusBar - ''    (L681, T766, R1762, B790)
   | ['Untitled-Notepad StatusBar', 'StatusBar   Windows (CRLF)', 'StatusBar100%', 'StatusBar', 'StatusBar 1 row, 1 column']
   | child_window(class_name="msctls_statusbar32")
>>>

Edit control found

Enter text in notepad

Write Hello World! And start a new line

>>> app[u"Untitled notepad"].Edit.set_edit_text(u"Hello World!")
<win32_controls.EditWrapper - 'Hello World!', Edit, 3672052>
>>>
>>> app[u"Untitled notepad"].Edit.type_keys("{ENTER}")
<win32_controls.EditWrapper - 'Hello World!
', Edit, 3672052>
>>>

notepad3.png

Save Notepad As

>>> app[u"Untitled notepad"].menu_select(u"File->save as")
>>>
>>> #Specify Save As dialog
>>> dialog = app[u"save as"]
>>>
>>> #Set file name
>>> dialog.Edit.set_edit_text(u"test")
<win32_controls.EditWrapper - 'test', Edit, 593534>
>>>
>>> #Press the save button
>>> dialog[u"Save"].click()
>>>

Since the file name has changed, the title bar has also changed

notepad4.png

Close notepad

Press Alt + F4 to close Notepad Alt key is "%"

Since the title bar has changed, change the designation from "Untitled Notepad"

>>> app[u"Test notepad"].type_keys("%{F4}")  # Alt + F4
<hwndwrapper.DialogWrapper - '', Notepad, 4261490>
>>>

Enumerate windows

>>> from pywinauto import Desktop
>>> top_windows = Desktop().windows()
>>> for w in top_windows:
...     print (w.window_text())
...

Connect to a launched app (Notepad)

Connect and view content

>>> from pywinauto import Desktop, Application
>>> app = Application().connect(path='notepad.exe')
>>>
>>> print ( app[u"Test notepad"].Edit.window_text() )
Hello World!

>>>
>>> print ( app[u"Test notepad"].Edit.texts() )
['Hello World!\r\n', 'Hello World!', '']
>>> print ( app[u"Test notepad"].Edit.text_block() )
Hello World!

>>>

Get the text of the specified line

>>> print ( app[u"Test notepad"].Edit.line_count() )
2
>>> print ( app[u"Test notepad"].Edit.get_line(0) )
Hello World!
>>> print ( app[u"Test notepad"].Edit.get_line(1) )

>>>

Get the text of the version information screen

>>> app[u"Test notepad"].menu_select(u"help->version information")
>>> for c in  app[u"Notepad version information"].children(class_name='Static') :
...     print ( c.window_text() )
...


Microsoft Windows
Version 1809(OS build 17763.1397)
© 2018 Microsoft Corporation. All rights reserved.

Windows 10 Enterprise operating system and user interface in the US and other countries/Protected by local trademarks and other intellectual property rights.

Windows users

>>>

notepad5.png

More information on the version information screen

>>> for c in  app[u"Notepad version information"].children() :
...     print ( c.get_properties() )   
...
{'class_name': 'Static', 'friendly_class_name': 'Static', 'texts': [''], 'control_id': 13095, 'rectangle': <RECT L618, T474, R1115, B476>, 'is_visible': True, 'is_enabled': True, 'control_count': 0, 'style': 1342177296, 'exstyle': 131076, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'MS UI Gothic' -12>], 'client_rects': [<RECT L0, T0, R495, B0>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
{'class_name': 'Static', 'friendly_class_name': 'Static', 'texts': [''], 'control_id': 12297, 'rectangle': <RECT L612, T493, R649, B531>, 'is_visible': True, 'is_enabled': True, 'control_count': 0, 'style': 1342177347, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'MS UI Gothic' -12>], 'client_rects': [<RECT L0, T0, R37, B38>], 'is_unicode': True, 'menu_items': [], 'automation_id': '', 'image': <PIL.Image.Image image mode=RGB size=37x38 at 0x1B6F8DFBAF0>}
{'class_name': 'Static', 'friendly_class_name': 'Static', 'texts': ['Microsoft Windows'], 'control_id': 13568, 'rectangle': <RECT L661, T493, R1064, B512>, 'is_visible': True, 'is_enabled': True, 'control_count': 0, 'style': 1342177420, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'Yu Gothic UI' -12>], 'client_rects': [<RECT L0, T0, R403, B19>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
{'class_name': 'Static', 'friendly_class_name': 'Static', 'texts': ['Version 1809(OS build 17763.1397)'], 'control_id': 13579, 'rectangle': <RECT L661, T512, R1125, B531>, 'is_visible': True, 'is_enabled': True, 'control_count': 0, 'style': 1342177420, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'Yu Gothic UI' -12>], 'client_rects': [<RECT L0, T0, R464, B19>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
{'class_name': 'Static', 'friendly_class_name': 'Static', 'texts': ['© 2018 Microsoft Corporation. All rights reserved.'], 'control_id': 13578, 'rectangle': <RECT L661, T530, R1081, B549>, 'is_visible': True, 'is_enabled': True, 'control_count': 0, 'style': 1342177408, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'Yu Gothic UI' -12>], 'client_rects': [<RECT L0, T0, R420, B19>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
{'class_name': 'Static', 'friendly_class_name': 'Static', 'texts': [''], 'control_id': 51715, 'rectangle': <RECT L661, T549, R1081, B568>, 'is_visible': False, 'is_enabled': True, 'control_count': 0, 'style': 1073741952, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'Yu Gothic UI' -12>], 'client_rects': [<RECT L0, T0, R420, B19>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
{'class_name': 'Static', 'friendly_class_name': 'Static', 'texts': ['Windows 10 Enterprise operating system and user interface in the US and other countries/Protected by local trademarks and other intellectual property rights.'], 'control_id': 13587, 'rectangle': <RECT L661, T568, R1081, B643>, 'is_visible': True, 'is_enabled': True, 'control_count': 0, 'style': 1342177408, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'Yu Gothic UI' -12>], 'client_rects': [<RECT L0, T0, R420, B75>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
{'class_name': 'Static', 'friendly_class_name': 'Static', 'texts': [''], 'control_id': 13581, 'rectangle': <RECT L661, T643, R1029, B681>, 'is_visible': False, 'is_enabled': True, 'control_count': 0, 'style': 1073741952, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'Yu Gothic UI' -12>], 'client_rects': [<RECT L0, T0, R368, B38>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
{'class_name': 'SysLink', 'friendly_class_name': 'SysLink', 'texts': ['This product is<A>Microsoft Software License Terms</A>It is licensed to the following people based on the conditions of.'], 'control_id': 13586, 'rectangle': <RECT L661, T680, R1029, B718>, 'is_visible': True, 'is_enabled': True, 'control_count': 0, 'style': 1342242816, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'Yu Gothic UI' -12>], 'client_rects': [<RECT L0, T0, R368, B38>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
{'class_name': 'Static', 'friendly_class_name': 'Static', 'texts': ['Windows users'], 'control_id': 13575, 'rectangle': <RECT L679, T718, R1047, B737>, 'is_visible': True, 'is_enabled': True, 'control_count': 0, 'style': 1342177408, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'Yu Gothic UI' -12>], 'client_rects': [<RECT L0, T0, R368, B19>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
{'class_name': 'Static', 'friendly_class_name': 'Static', 'texts': [''], 'control_id': 13576, 'rectangle': <RECT L679, T737, R1047, B756>, 'is_visible': True, 'is_enabled': True, 'control_count': 0, 'style': 1342177408, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'Yu Gothic UI' -12>], 'client_rects': [<RECT L0, T0, R368, B19>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
{'class_name': 'Button', 'friendly_class_name': 'Button', 'texts': ['OK'], 'control_id': 1, 'rectangle': <RECT L1038, T791, R1126, B817>, 'is_visible': True, 'is_enabled': True, 'control_count': 0, 'style': 1342242816, 'exstyle': 4, 'user_data': 0, 'context_help_id': 0, 'fonts': [<LOGFONTW 'Yu Gothic UI' -12>], 'client_rects': [<RECT L0, T0, R88, B26>], 'is_unicode': True, 'menu_items': [], 'automation_id': ''}
>>>

List the buttons on the version information screen

>>> #Number of buttons
>>> len( app[u"Notepad version information"].children(class_name="Button") )
1
>>> #Button information enumeration
>>> for b in app[u"Notepad version information"].children(class_name="Button") :
...     print ( b.window_text() + "  visible:" + str(b.is_visible()) + "  enabled:" + str(b.is_enabled()) )
...
OK  visible:True  enabled:True
>>>

Check the operation with Explorer

Open My Documents

C:\>python
Python 3.8.5 (tags/v3.8.5:580fbb0, Jul 20 2020, 15:57:54) [MSC v.1924 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from pywinauto import Application
>>> Application().start('explorer.exe')
<pywinauto.application.Application object at 0x0000021F459F0FD0>
>>> app = Application().connect(path='explorer.exe')
>>>
>>> #Connection confirmation
>>> app[u"Explorer"].exists()
True
>>>
>>> #My document folder path setting
>>> import os
>>> mydocument = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Documents')
>>>
>>> #Open My Documents folder
>>> app[u"Explorer"].AddressBandRoot.type_keys(u"{ENTER}" + mydocument + "{ENTER}")
<hwndwrapper.HwndWrapper - '', Address Band Root, 264944>
>>>

explorer1.png

Get the file list of My Documents

>>> from pywinauto import Desktop
>>> d = Desktop(backend='uia')[u"document"]
>>> d.ListBox.get_properties()
{'class_name': 'UIItemsView', 'friendly_class_name': 'ListBox', 'texts': [['', 'name', 'Update date and time', 'type', 'size'], ['', 'name', 'Update date and time', 'type', 'size'], ['', 'name', 'Update date and time', 'type', 'size']], 'control_id': 0, 'rectangle': <RECT L947, T306, R1605, B767>, 'is_visible': True, 'is_enabled': True, 'control_count': 5, 'is_keyboard_focusable': False, 'has_keyboard_focus': False, 'automation_id': '', 'column_count': 4, 'item_count': 3, 'columns': [<uiawrapper.UIAWrapper - 'name', SplitButton, -5173013587085247480>, <uiawrapper.UIAWrapper - 'Update date and time', SplitButton, 7405196887091890411>, <uiawrapper.UIAWrapper - 'type', SplitButton, 4224075079785634787>, <uiawrapper.UIAWrapper - 'size', SplitButton, 7052361179099937348>]}
>>>
>>> #The number of lines in the list is
>>> d.ListBox.item_count()
3
>>>
>>> #List display of list
>>> for i in d.ListBox.get_items() :
...     i.window_text()
...
'Office custom template'
'pywinauto'
'UISpy Settings'
>>>

Control names and hierarchical structure can be helpful by using a tool called UISPY. Download from this area https://github.com/blackrosezy/gui-inspect-tool

explorer2.png

If you just want a list of files, you don't need to use pywinauto

>>> import os
>>> mydocument = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Documents')
>>> for file in os.listdir( mydocument ) :
...     print( file )
...
Default.rdp
desktop.ini
My Music
My Pictures
My Videos
Office custom template
pywinauto
UISpy Settings
>>>

that? You can see hidden files that you can't see. ..

Move folder from My Documents

>>> d = Desktop(backend='uia')[u"document"]
>>> d.ListBox[u"Office custom template"].invoke()
<uia_controls.ListItemWrapper - 'Office custom template', ListItem, 8579292259166560630>
>>>

Recommended Posts

Notes on how to use pywinauto
Notes on how to use featuretools
Notes on how to use doctest
How to use Dataiku on Windows
How to use homebrew on Debian
Autoencoder with Chainer (Notes on how to use + trainer)
Notes on how to write requirements.txt
[Hyperledger Iroha] Notes on how to use the Python SDK
Notes on how to use marshmallow in the schema library
How to use mecab, neologd-ipadic on colab
How to use Google Assistant on Windows 10
Memorandum on how to use gremlin python
How to use xml.etree.ElementTree
How to use Python-shell
How to use tf.data
How to use Seaboan
How to use image-match
How to use shogun
How to use Pandas 2
How to use Virtualenv
How to use numpy.vectorize
How to use pytest_report_header
How to use partial
How to use Bio.Phylo
How to use SymPy
How to use x-means
How to use WikiExtractor.py
How to use IPython
How to use virtualenv
How to use Matplotlib
How to use iptables
How to use numpy
How to use TokyoTechFes2015
How to use venv
How to use dictionary {}
How to use Pyenv
How to use list []
How to use python-kabusapi
How to use OptParse
How to use return
How to use dotenv
How to use pyenv-virtualenv
How to use Go.mod
How to use imutils
How to use import
How to use Python Kivy ④ ~ Execution on Android ~
How to use Qt Designer
How to use search sorted
[gensim] How to use Doc2Vec
python3: How to use bottle (2)
Understand how to use django-filter
How to use the generator
[Python] How to use list 1
How to use FastAPI ③ OpenAPI
How to register on pypi
How to use Python argparse
How to use IPython Notebook
How to use Pandas Rolling
[Note] How to use virtualenv
How to use redis-py Dictionaries
Python: How to use pydub