LoginSignup
28
22

More than 3 years have passed since last update.

pywinauto の使い方メモ

Last updated at Posted at 2020-09-30

pywinauto の使い方メモ

メモ帳で動作確認

アプリを起動(メモ帳)

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
>>>
>>> # メモ帳を起動
>>> app = Application().start('notepad.exe')

バージョン情報を表示

メニューの「ヘルプ」の「バージョン情報」を選択してバージョン情報画面を表示

>>> # ヘルプ -> バージョン情報 を表示
>>> app[u"無題メモ帳"].menu_select(u"ヘルプ -> バージョン情報")

notepad2.png

バージョン情報画面の存在確認

>>> print ( app[u"メモ帳 のバージョン情報"].exists() )
True
>>>

バージョン情報画面のコントロール情報を取得

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

Dialog - 'メモ帳 のバージョン情報'    (L690, T232, R1240, B711)
['メモ帳 のバージョン情報', 'Dialog', 'メモ帳 のバージョン情報Dialog']
child_window(title="メモ帳 のバージョン情報", class_name="#32770")
   |
   | Static - ''    (L716, T348, R1213, B350)
   | ['メモ帳 のバージョン情報Static', 'Static', 'メモ帳 のバージョン情報Static0', 'メモ帳 のバージョン情報Static1', 'Static0', 'Static1']
   | child_window(class_name="Static")
   |
   | Static - ''    (L710, T367, R747, B405)
   | ['メモ帳 のバージョン情報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 - 'バージョン 1809 (OS ビルド 17763.1397)'    (L759, T386, R1223, B405)
   | ['バージョン 1809 (OS ビルド 17763.1397)', 'Static4', 'バージョン 1809 (OS ビルド 17763.1397)Static']
   | child_window(title="バージョン 1809 (OS ビルド 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 オペレーティング システムとユーザー インターフェイスは、米国およびその他の国/地域の商標およびその他の知的所有権によって保護されています。'    (L759, T442, R1179, B517)
   | ['Static7', 'Windows 10 Enterprise オペレーティング システムとユーザー インターフェイスは、米国およびその他の国/地 域の商標およびその他の知的所有権によって保護されています。', 'Windows 10 Enterprise オペレーティング システムとユーザー インターフェイスは、米国およびその他の国/地域の商標およびその他の知的所有権によって保護されています。Static', 'Windows 10 Enterprise オペレーティング システムとユーザー インターフェイスは、米国およびその他の国/地域の商標およびその他の知的所有権によって保護されています。Static0', 'Windows 10 Enterprise オペレーティング システムとユーザー インターフェイスは、 米国およびその他の国/地域の商標およびその他の知的所有権によって保護されています。Static1']
   | child_window(title="Windows 10 Enterprise オペレーティング システムとユーザー インターフェイスは、米国およびその他 の国/地域の商標およびその他の知的所有権によって保護されています。", class_name="Static")
   |
   | Static - ''    (L759, T517, R1127, B555)
   | ['Static8', 'Windows 10 Enterprise オペレーティング システムとユーザー インターフェイスは、米国およびその他の国/地 域の商標およびその他の知的所有権によって保護されています。Static2']
   | child_window(class_name="Static")
   |
   | SysLink - 'この製品は<A>マイクロソフト ソフトウェア ライセンス条項</A>の条件に基づいて次の方にライセンスされていま す。'    (L759, T554, R1127, B592)
   | ['この製品は<A>マイクロソフト ソフトウェア ライセンス条項</A>の条件に基づいて次の方にライセンスされています。', 'この製品は<A>マイクロソフト ソフトウェア ライセンス条項</A>の条件に基づいて次の方にライセンスされています。SysLink', 'SysLink']
   | child_window(title="この製品は<A>マイクロソフト ソフトウェア ライセンス条項</A>の条件に基づいて次の方にライセンスされています。", class_name="SysLink")
   |
   | Static - 'Windows ユーザー'    (L777, T592, R1145, B611)
   | ['Windows ユーザーStatic', 'Static9', 'Windows ユーザー', 'Windows ユーザーStatic0', 'Windows ユーザーStatic1']
   | child_window(title="Windows ユーザー", class_name="Static")
   |
   | Static - ''    (L777, T611, R1145, B630)
   | ['Windows ユーザーStatic2', 'Static10']
   | child_window(class_name="Static")
   |
   | Button - 'OK'    (L1136, T665, R1224, B691)
   | ['OKButton', 'OK', 'Button']
   | child_window(title="OK", class_name="Button")
>>>

バージョン情報画面を閉じる

OK ボタンを押してバージョン情報画面を閉じる

>>> app[u"メモ帳 のバージョン情報"].OK.close_click()
<win32_controls.ButtonWrapper - '', Button, 462076>
>>>

メモ帳のコントロール情報を表示

>>> app[u"無題メモ帳"].dump_tree()
Control Identifiers:

Notepad - '無題 - メモ帳'    (L673, T177, R1770, B798)
['無題 - メモ帳', 'Notepad', '無題 - メモ帳Notepad']
child_window(title="無題 - メモ帳", class_name="Notepad")
   |
   | Edit - ''    (L681, T228, R1762, B766)
   | ['Edit', '無題 - メモ帳Edit']
   | child_window(class_name="Edit")
   |
   | StatusBar - ''    (L681, T766, R1762, B790)
   | ['無題 - メモ帳StatusBar', 'StatusBar   Windows (CRLF)', 'StatusBar100%', 'StatusBar', 'StatusBar   1 行、1 列  ']
   | child_window(class_name="msctls_statusbar32")
>>>

Edit コントロールが見つかった

メモ帳にテキストを入力

Hello World! と書いて、改行

>>> app[u"無題メモ帳"].Edit.set_edit_text(u"Hello World!")
<win32_controls.EditWrapper - 'Hello World!', Edit, 3672052>
>>>
>>> app[u"無題メモ帳"].Edit.type_keys("{ENTER}")
<win32_controls.EditWrapper - 'Hello World!
', Edit, 3672052>
>>>

notepad3.png

メモ帳を名前を付けて保存

>>> app[u"無題メモ帳"].menu_select(u"ファイル -> 名前を付けて保存")
>>>
>>> # 名前を付けて保存のダイアログを指定
>>> dialog = app[u"名前を付けて保存"]
>>>
>>> # ファイル名を設定
>>> dialog.Edit.set_edit_text(u"テスト")
<win32_controls.EditWrapper - 'テスト', Edit, 593534>
>>>
>>> # 保存ボタンを押す
>>> dialog[u"保存"].click()
>>>

ファイル名が変わったので、タイトルバーも変わってる

notepad4.png

メモ帳を閉じる

Alt + F4 キーを押してメモ帳を閉じる
Alt キーは "%"

タイトルバーが変わってるので指定も「無題メモ帳」から変えておく

>>> app[u"テスト メモ帳"].type_keys("%{F4}")  # Alt + F4
<hwndwrapper.DialogWrapper - '', Notepad, 4261490>
>>>

ウィンドウを列挙

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

起動済みのアプリに接続(メモ帳)

接続して、内容を表示

>>> from pywinauto import Desktop, Application
>>> app = Application().connect(path='notepad.exe')
>>>
>>> print ( app[u"テスト メモ帳"].Edit.window_text() )
Hello World!

>>>
>>> print ( app[u"テスト メモ帳"].Edit.texts() )
['Hello World!\r\n', 'Hello World!', '']
>>> print ( app[u"テスト メモ帳"].Edit.text_block() )
Hello World!

>>>

指定行のテキストを取得

>>> print ( app[u"テスト メモ帳"].Edit.line_count() )
2
>>> print ( app[u"テスト メモ帳"].Edit.get_line(0) )
Hello World!
>>> print ( app[u"テスト メモ帳"].Edit.get_line(1) )

>>>

バージョン情報画面のテキストを取得

>>> app[u"テスト メモ帳"].menu_select(u"ヘルプ -> バージョン情報")
>>> for c in  app[u"メモ帳 のバージョン情報"].children(class_name='Static') :
...     print ( c.window_text() )
...


Microsoft Windows
バージョン 1809 (OS ビルド 17763.1397)
© 2018 Microsoft Corporation. All rights reserved.

Windows 10 Enterprise オペレーティング システムとユーザー インターフェイスは米国およびその他の国/地域の商標およびその 他の知的所有権によって保護されています

Windows ユーザー

>>>

notepad5.png

バージョン情報画面のもっと詳しい情報

>>> for c in  app[u"メモ帳 のバージョン情報"].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': ['バージョン 1809 (OS ビルド 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 オペレーティング システムとユーザー インターフェイスは、米国およびその他の国/地域の商標およびその他の知的所有権によって保護されています。'], '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': ['この製品は<A>マイクロソフト ソフトウェア ライセンス条項</A>の条件に基づいて次の方にライセンスされています。'], '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 ユーザー'], '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': ''}
>>>

バージョン情報画面のボタンを列挙

>>> # ボタン数
>>> len( app[u"メモ帳 のバージョン情報"].children(class_name="Button") )
1
>>> # ボタンの情報列挙
>>> for b in app[u"メモ帳 のバージョン情報"].children(class_name="Button") :
...     print ( b.window_text() + "  visible:" + str(b.is_visible()) + "  enabled:" + str(b.is_enabled()) )
...
OK  visible:True  enabled:True
>>>

エクスプローラー で動作確認

マイドキュメントを開く

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')
>>>
>>> # 接続確認
>>> app[u"エクスプローラー"].exists()
True
>>>
>>> # マイドキュメントフォルダパス設定
>>> import os
>>> mydocument = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Documents')
>>>
>>> # マイドキュメントフォルダを開く
>>> app[u"エクスプローラー"].AddressBandRoot.type_keys(u"{ENTER}" + mydocument + "{ENTER}")
<hwndwrapper.HwndWrapper - '', Address Band Root, 264944>
>>>

explorer1.png

マイドキュメントのファイル一覧を取得する

>>> from pywinauto import Desktop
>>> d = Desktop(backend='uia')[u"ドキュメント"]
>>> d.ListBox.get_properties()
{'class_name': 'UIItemsView', 'friendly_class_name': 'ListBox', 'texts': [['', '名前', '更新日時', '種類', 'サイズ'], ['', '名前', '更新日時', '種類', 'サイズ'], ['', '名前', '更新日時', '種類', 'サイズ']], '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 - '名前', SplitButton, -5173013587085247480>, <uiawrapper.UIAWrapper - '更新日時', SplitButton, 7405196887091890411>, <uiawrapper.UIAWrapper - '種類', SplitButton, 4224075079785634787>, <uiawrapper.UIAWrapper - 'サイズ', SplitButton, 7052361179099937348>]}
>>>
>>> # 一覧の行数は
>>> d.ListBox.item_count()
3
>>>
>>> # 一覧のリスト表示
>>> for i in d.ListBox.get_items() :
...     i.window_text()
...
'Office のカスタム テンプレート'
'pywinauto'
'UISpy Settings'
>>>

コントロール名称や階層構造などは UISPY というツールを使うと参考になる
この辺からダウンロードとか 
https://github.com/blackrosezy/gui-inspect-tool

explorer2.png

ファイル一覧が欲しいだけなら 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 のカスタム テンプレート
pywinauto
UISpy Settings
>>>

あれ?見えていない隠しファイルなんかも見えちゃってますね。。

マイドキュメントからフォルダ移動

>>> d = Desktop(backend='uia')[u"ドキュメント"]
>>> d.ListBox[u"Office のカスタム テンプレート"].invoke()
<uia_controls.ListItemWrapper - 'Office のカスタム テンプレート', ListItem, 8579292259166560630>
>>>

ドキュメントはこちら
https://pywinauto.readthedocs.io/en/latest/contents.html
https://pywinauto.readthedocs.io/_/downloads/en/atspi/pdf/

28
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
22