Contents¶
What is pywinauto¶
© Mark Mc Mahon and Contributors, 2006-2018
Released under the BSD 3-clause license
What is it?¶
pywinauto是一组用于自动化Microsoft Windows GUI的python模块。 最简单的是,它允许您将鼠标和键盘操作发送到Windows对话框和控件。
Installation¶
- Just run
pip install pywinauto
Manual installation¶
- Install the following Python packages
- Download latest pywinauto from https://github.com/pywinauto/pywinauto/releases
- Unpack and run
python setup.py install
To check you have it installed correctly Run Python
>>> from pywinauto.application import Application
>>> app = Application(backend="uia").start("notepad.exe")
>>> app.UntitledNotepad.type_keys("%FX")
How does it work¶
入门指南中描述了核心概念。
通过每个类的属性访问(__ getattribute __
)完成了很多工作。 例如,当您获得Application或Dialog对象的属性时,它会分别查找对话框或控件。
myapp.Notepad # looks for a Window/Dialog of your app that has a title 'similar'
# to "Notepad"
myapp.PageSetup.OK # looks first for a dialog with a title like "PageSetup"
# then it looks for a control on that dialog with a title
# like "OK"
此属性解析会延迟(使用默认超时),直到成功为止。 因此,例如,如果您选择菜单选项,然后查找结果对话框,例如
app.UntitledNotepad.menu_select("File->SaveAs")
app.SaveAs.ComboBox5.select("UTF-8")
app.SaveAs.edit1.set_text("Example-utf8.txt")
app.SaveAs.Save.click()
在第2行,执行此行时可能无法打开SaveAs对话框。 所以会发生什么,我们要等到我们有一个控件要解决之前解决对话框。 此时,如果我们找不到带有ComboBox5控件的SaveAs对话框,那么我们会等待很短的时间再试一次,这会重复到最大时间(目前为5秒!)
这是为了避免必须明确使用time.sleep或“wait”函数。
如果您的应用程序执行长时间操作,则新对话框可能会在以后显示或消失。 你可以等待它的新状态
app.Open.Open.click() # opening large file
app.Open.wait_not('visible') # make sure "Open" dialog became invisible
# wait for up to 30 seconds until data.txt is loaded
app.window(title='data.txt - Notepad').wait('ready', timeout=30)
一些类似的工具用于比较¶
- Python tools
- PyAutoGui - 一个流行的跨平台库(具有基于图像的搜索,没有基于文本的控件操作)。
- Lackey - Sikuli的纯Python替代品(基于图像模式匹配)。
- AXUI - MS UI Automation API的一个包装器。
- winGuiAuto - 使用Win32 API的另一个模块。
- Other scripting language tools
- (Perl) Win32::GuiTest
- (Ruby) Win32-Autogui - a wrapper around Win32 API.
- (Ruby) RAutomation - there are 3 adapters: Win32 API, UIA, AutoIt.
- Other free tools
- (C#) Winium.Desktop - a young but good MS UI Automation based tool.
- (C#) TestStack.White - another good MS UI Automation based library with a long history.
- AutoIt - 具有类似Basic语言的免费工具(基于Win32 API,无.NET计划)
- AutoHotKey - 具有自己的脚本语言(.ahk)的本机C++工具
- “Awesome test automation” list on GitHub
- 用于功能测试的大量开源工具
Why write yet another automation tool if there are so many out there?¶
There are loads of reasons :-)
- Takes a different approach:
大多数其他工具不是面向对象的,你最终写的东西如下:
window = findwindow(title = "Untitled - Notepad", class = "Notepad") SendKeys(window, "%OF") # Format -> Font fontdialog = findwindow("title = "Font") buttonClick(fontdialog, "OK")
我希望创造一些更加用户友好(和pythonic)的东西。 例如,上面的翻译将是:
win = app.UntitledNotepad win.menu_select("Format->Font") app.Font.OK.click()
- Python makes it easy:
- Python是一种很棒的编程语言,但没有自动化工具是Pythonic(极少数库是用Python实现的)。
- Localization as a main requirement:
Mark:
“I work in the localization industry and GUI automation is used extensively as often all you need to do is ensure that your UI behaves and is correct with respect to the Source UI. This is actually an easier job then for testing the original source UI.
But most automation tools are based off of coordinates or text of the controls and these can change in the localized software. So my goal ( though not yet implemented) is to allow scripts to run unchanged between original source language (often English) and the translated software (Japanese, German, etc).”
Getting Started Guide¶
Once you have installed pywinauto - how do you get going? The very first necessary thing is to determine which accessibility technology (pywinauto’s backend) could be used for your application.
The list of supported accessibility technologies on Windows:
- Win32 API (
backend="win32"
) - a default backend for now
- MFC,VB6,VCL,简单的WinForms控件和大多数旧的遗留应用程序
- MS UI Automation (
backend="uia"
)
- WinForms,WPF,商店应用,Qt5,浏览器
注意:Chrome在启动之前需要
- force-renderer-accessibility
cmd标志。 由于comtypes Python库限制,不支持自定义属性和控件。
Not supported: Java AWT/Swing, GTK+, Tkinter.
到目前为止,Linux上的AT SPI和Apple Accessibility API都是长期计划。
GUI Objects Inspection / Spy Tools¶
如果您仍然不确定哪个后端最适合您,请尝试使用免费提供的对象检查/间谍工具:从GitHub repo gui-inspect-tool下载它们。
Spy++包含在MS Visual Studio发行版(甚至是Express或Community)中,可通过“开始”菜单访问。 It uses Win32 API. 这意味着如果Spy++可以显示所有控件,那么
“win32”
后端就是您所需要的。 AutoIt窗口信息工具是一种间谍克隆。Inspect.exe是Microsoft创建的另一个很棒的工具。 它包含在Windows SDK中,因此可以在x64 Windows上的以下位置找到它:
C:\Program Files (x86)\Windows Kits\<winver>\bin\x64
将Inspect.exe切换到UIA模式(使用MS UI Automation)。 如果它可以显示比Spy更多的控件及其属性,那么可能是
“uia”
后端是你的选择。
Entry Points for Automation¶
所以你有一个应用程序,你知道它支持上面提到的一种可访问性技术。 What’s the next?
首先,您应该启动应用程序或连接到现有的应用程序实例。 可以使用Application
对象完成。 这不仅仅是subprocess.Popen
的克隆,而是进一步自动化的入口点,通过过程边界限制所有范围。 控制应用程序的潜在极少数实例很有用(您使用一个不打扰另一个实例的实例)。
from pywinauto.application import Application app = Application(backend="uia").start('notepad.exe') # describe the window inside Notepad.exe process dlg_spec = app.UntitledNotepad # wait till the window is really open actionable_dlg = dlg_spec.wait('visible')
如果您想跨越流程边界(例如,Win10计算器令人惊讶地在多个流程中绘制其小部件),您的入口点是Desktop
对象。
from subprocess import Popen from pywinauto import Desktop Popen('calc.exe', shell=True) dlg = Desktop(backend="uia").Calculator dlg.wait('visible')
Application和Destop对象都是特定于后端的。 无需在后续操作中明确使用后端名称。
Window Specification¶
这是高级pywinauto API的核心概念。 您可以近似或更详细地描述任何窗口或控件,即使它尚不存在或已经关闭。 窗口规范还保留有关将用于获得真实窗口或控件的匹配/搜索算法的信息。
让我们创建一个详细的窗口规范:
>>> dlg_spec = app.window(title='Untitled - Notepad') >>> dlg_spec <pywinauto.application.WindowSpecification object at 0x0568B790> >>> dlg_spec.wrapper_object() <pywinauto.controls.win32_controls.DialogWrapper object at 0x05639B70>
实际窗口查找由wrapper_object()
方法执行。 它返回实际现有窗口/控件的一些包装器或引发ElementNotFoundError
。
此包装器可以通过发送操作或检索数据来处理窗口/控件。
但Python可以隐藏这个wrapper_object()
调用,以便您在生产中拥有更紧凑的代码。 以下陈述完全相同:
dlg_spec.wrapper_object().minimize() # while debugging dlg_spec.minimize() # in production
创建窗口规范有许多可能的标准。 These are just a few examples.
# can be multi-level app.window(title_re='.* - Notepad$').window(class_name='Edit') # can combine criteria dlg = Desktop(backend="uia").Calculator dlg.window(auto_id='num8Button', control_type='Button')
可以在pywinauto.findwindows.find_elements()
函数中找到可能的标准列表。
Attribute Resolution Magic¶
Python通过动态解析对象属性简化了创建窗口规范。 但是一个属性名称与任何变量名称具有相同的限制:没有空格,逗号和其他特殊符号。 但幸运的是pywinauto使用“最佳匹配”算法来查找拼写错误和小变化。
app.UntitledNotepad # is equivalent to app.window(best_match='UntitledNotepad')
通过类似字典的项目访问,可以使用Unicode字符和特殊符号。
app['Untitled - Notepad'] # is the same as app.window(best_match='Untitled - Notepad')
How to know magic attribute names¶
如何将“最佳匹配”金牌附加到控件上有几个原则。 因此,如果窗口规范接近其中一个名称,您将获得成功的名称匹配。
- By title (window text, name):
app.Properties.OK.click()
- By title and control type:
app.Properties.OKButton.click()
- By control type and number:
app.Properties.Button3.click()
(Note: Button0 and Button1 match the same button, Button2 is the next etc.) - By top-left label and control type:
app.OpenDialog.FileNameEdit.set_text("")
- By control type and item text:
app.Properties.TabControlSharing.select("General")
通常并非所有这些匹配的名称都可以同时使用。 要检查指定对话框的这些名称,可以使用print_control_identifiers()
方法。 可能的“best_match”名称显示为树中每个控件的Python列表。 也可以从方法输出中复制更详细的窗口规范。 Say
app.Properties.child_window(title="Contains:", auto_id="13087", control_type="Edit")
.
>>> app.Properties.print_control_identifiers() Control Identifiers: Dialog - 'Windows NT Properties' (L688, T518, R1065, B1006) [u'Windows NT PropertiesDialog', u'Dialog', u'Windows NT Properties'] child_window(title="Windows NT Properties", control_type="Window") | | Image - '' (L717, T589, R749, B622) | [u'', u'0', u'Image1', u'Image0', 'Image', u'1'] | child_window(auto_id="13057", control_type="Image") | | Image - '' (L717, T630, R1035, B632) | ['Image2', u'2'] | child_window(auto_id="13095", control_type="Image") | | Edit - 'Folder name:' (L790, T596, R1036, B619) | [u'3', 'Edit', u'Edit1', u'Edit0'] | child_window(title="Folder name:", auto_id="13156", control_type="Edit") | | Static - 'Type:' (L717, T643, R780, B658) | [u'Type:Static', u'Static', u'Static1', u'Static0', u'Type:'] | child_window(title="Type:", auto_id="13080", control_type="Text") | | Edit - 'Type:' (L790, T643, R1036, B666) | [u'4', 'Edit2', u'Type:Edit'] | child_window(title="Type:", auto_id="13059", control_type="Edit") | | Static - 'Location:' (L717, T669, R780, B684) | [u'Location:Static', u'Location:', u'Static2'] | child_window(title="Location:", auto_id="13089", control_type="Text") | | Edit - 'Location:' (L790, T669, R1036, B692) | ['Edit3', u'Location:Edit', u'5'] | child_window(title="Location:", auto_id="13065", control_type="Edit") | | Static - 'Size:' (L717, T695, R780, B710) | [u'Size:Static', u'Size:', u'Static3'] | child_window(title="Size:", auto_id="13081", control_type="Text") | | Edit - 'Size:' (L790, T695, R1036, B718) | ['Edit4', u'6', u'Size:Edit'] | child_window(title="Size:", auto_id="13064", control_type="Edit") | | Static - 'Size on disk:' (L717, T721, R780, B736) | [u'Size on disk:', u'Size on disk:Static', u'Static4'] | child_window(title="Size on disk:", auto_id="13107", control_type="Text") | | Edit - 'Size on disk:' (L790, T721, R1036, B744) | ['Edit5', u'7', u'Size on disk:Edit'] | child_window(title="Size on disk:", auto_id="13106", control_type="Edit") | | Static - 'Contains:' (L717, T747, R780, B762) | [u'Contains:1', u'Contains:0', u'Contains:Static', u'Static5', u'Contains:'] | child_window(title="Contains:", auto_id="13088", control_type="Text") | | Edit - 'Contains:' (L790, T747, R1036, B770) | [u'8', 'Edit6', u'Contains:Edit'] | child_window(title="Contains:", auto_id="13087", control_type="Edit") | | Image - 'Contains:' (L717, T773, R1035, B775) | [u'Contains:Image', 'Image3', u'Contains:2'] | child_window(title="Contains:", auto_id="13096", control_type="Image") | | Static - 'Created:' (L717, T786, R780, B801) | [u'Created:', u'Created:Static', u'Static6', u'Created:1', u'Created:0'] | child_window(title="Created:", auto_id="13092", control_type="Text") | | Edit - 'Created:' (L790, T786, R1036, B809) | [u'Created:Edit', 'Edit7', u'9'] | child_window(title="Created:", auto_id="13072", control_type="Edit") | | Image - 'Created:' (L717, T812, R1035, B814) | [u'Created:Image', 'Image4', u'Created:2'] | child_window(title="Created:", auto_id="13097", control_type="Image") | | Static - 'Attributes:' (L717, T825, R780, B840) | [u'Attributes:Static', u'Static7', u'Attributes:'] | child_window(title="Attributes:", auto_id="13091", control_type="Text") | | CheckBox - 'Read-only (Only applies to files in folder)' (L790, T825, R1035, B841) | [u'CheckBox0', u'CheckBox1', 'CheckBox', u'Read-only (Only applies to files in folder)CheckBox', u'Read-only (Only applies to files in folder)'] | child_window(title="Read-only (Only applies to files in folder)", auto_id="13075", control_type="CheckBox") | | CheckBox - 'Hidden' (L790, T848, R865, B864) | ['CheckBox2', u'HiddenCheckBox', u'Hidden'] | child_window(title="Hidden", auto_id="13076", control_type="CheckBox") | | Button - 'Advanced...' (L930, T845, R1035, B868) | [u'Advanced...', u'Advanced...Button', 'Button', u'Button1', u'Button0'] | child_window(title="Advanced...", auto_id="13154", control_type="Button") | | Button - 'OK' (L814, T968, R889, B991) | ['Button2', u'OK', u'OKButton'] | child_window(title="OK", auto_id="1", control_type="Button") | | Button - 'Cancel' (L895, T968, R970, B991) | ['Button3', u'CancelButton', u'Cancel'] | child_window(title="Cancel", auto_id="2", control_type="Button") | | Button - 'Apply' (L976, T968, R1051, B991) | ['Button4', u'ApplyButton', u'Apply'] | child_window(title="Apply", auto_id="12321", control_type="Button") | | TabControl - '' (L702, T556, R1051, B962) | [u'10', u'TabControlSharing', u'TabControlPrevious Versions', u'TabControlSecurity', u'TabControl', u'TabControlCustomize'] | child_window(auto_id="12320", control_type="Tab") | | | | TabItem - 'General' (L704, T558, R753, B576) | | [u'GeneralTabItem', 'TabItem', u'General', u'TabItem0', u'TabItem1'] | | child_window(title="General", control_type="TabItem") | | | | TabItem - 'Sharing' (L753, T558, R801, B576) | | [u'Sharing', u'SharingTabItem', 'TabItem2'] | | child_window(title="Sharing", control_type="TabItem") | | | | TabItem - 'Security' (L801, T558, R851, B576) | | [u'Security', 'TabItem3', u'SecurityTabItem'] | | child_window(title="Security", control_type="TabItem") | | | | TabItem - 'Previous Versions' (L851, T558, R947, B576) | | [u'Previous VersionsTabItem', u'Previous Versions', 'TabItem4'] | | child_window(title="Previous Versions", control_type="TabItem") | | | | TabItem - 'Customize' (L947, T558, R1007, B576) | | [u'CustomizeTabItem', 'TabItem5', u'Customize'] | | child_window(title="Customize", control_type="TabItem") | | TitleBar - 'None' (L712, T521, R1057, B549) | ['TitleBar', u'11'] | | | | Menu - 'System' (L696, T526, R718, B548) | | [u'System0', u'System', u'System1', u'Menu', u'SystemMenu'] | | child_window(title="System", auto_id="MenuBar", control_type="MenuBar") | | | | | | MenuItem - 'System' (L696, T526, R718, B548) | | | [u'System2', u'MenuItem', u'SystemMenuItem'] | | | child_window(title="System", control_type="MenuItem") | | | | Button - 'Close' (L1024, T519, R1058, B549) | | [u'CloseButton', u'Close', 'Button5'] | | child_window(title="Close", control_type="Button")
Look at the examples¶
包括以下示例:注意:示例取决于语言 - 它们仅适用于为其编程的产品语言。 除非突出显示,否则所有示例都已编程为英语软件。
mspaint.py
Control MSPaintnotepad_fast.py
使用快速计时设置来控制记事本notepad_slow.py
使用慢速计时设置来控制记事本notepad_item.py
Use item rather then attribute access to control Notepad.misc_examples.py
Show some exceptions and how to get control identifiers.save_from_internet_explorer.py
Save a Web Page from Internet Explorer.save_from_firefox.py
Save a Web Page from Firefox.get_winrar_info.py
Example of how to do multilingual automation. This is not an ideal example (works on French, Czech and German WinRar)forte_agent_sample.py
Example of dealing with a complex application that is quite dynamic and gives different dialogs often when starting.windowmediaplayer.py
Just another example - deals with check boxes in a ListView.test_sakura.py
,test_sakura2.py
Two examples of automating a Japanase product.
Automate notepad at the command line¶
Please find below a sample run
C:\>python
Python 2.4.2 (#67, Sep 28 2005, 12:41:11) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(1) >>> from pywinauto import application
(2) >>> app = application.Application()
(3) >>> app.start("Notepad.exe")
<pywinauto.application.Application object at 0x00AE0990>
(4) >>> app.UntitledNotepad.draw_outline()
(5) >>> app.UntitledNotepad.menu_select("Edit -> Replace")
(6) >>> app.Replace.print_control_identifiers()
Control Identifiers:
Dialog - 'Replace' (L179, T174, R657, B409)
['ReplaceDialog', 'Dialog', 'Replace']
child_window(title="Replace", class_name="#32770")
|
| Static - 'Fi&nd what:' (L196, T230, R292, B246)
| ['Fi&nd what:Static', 'Fi&nd what:', 'Static', 'Static0', 'Static1']
| child_window(title="Fi&nd what:", class_name="Static")
|
| Edit - '' (L296, T226, R524, B250)
| ['Fi&nd what:Edit', 'Edit', 'Edit0', 'Edit1']
| child_window(class_name="Edit")
|
| Static - 'Re&place with:' (L196, T264, R292, B280)
| ['Re&place with:', 'Re&place with:Static', 'Static2']
| child_window(title="Re&place with:", class_name="Static")
|
| Edit - '' (L296, T260, R524, B284)
| ['Edit2', 'Re&place with:Edit']
| child_window(class_name="Edit")
|
| CheckBox - 'Match &whole word only' (L198, T304, R406, B328)
| ['CheckBox', 'Match &whole word onlyCheckBox', 'Match &whole word only', 'CheckBox0', 'CheckBox1']
| child_window(title="Match &whole word only", class_name="Button")
|
| CheckBox - 'Match &case' (L198, T336, R316, B360)
| ['CheckBox2', 'Match &case', 'Match &caseCheckBox']
| child_window(title="Match &case", class_name="Button")
|
| Button - '&Find Next' (L536, T220, R636, B248)
| ['&Find Next', '&Find NextButton', 'Button', 'Button0', 'Button1']
| child_window(title="&Find Next", class_name="Button")
|
| Button - '&Replace' (L536, T254, R636, B282)
| ['&ReplaceButton', '&Replace', 'Button2']
| child_window(title="&Replace", class_name="Button")
|
| Button - 'Replace &All' (L536, T288, R636, B316)
| ['Replace &AllButton', 'Replace &All', 'Button3']
| child_window(title="Replace &All", class_name="Button")
|
| Button - 'Cancel' (L536, T322, R636, B350)
| ['CancelButton', 'Cancel', 'Button4']
| child_window(title="Cancel", class_name="Button")
|
| Button - '&Help' (L536, T362, R636, B390)
| ['&Help', '&HelpButton', 'Button5']
| child_window(title="&Help", class_name="Button")
|
| Static - '' (L196, T364, R198, B366)
| ['ReplaceStatic', 'Static3']
| child_window(class_name="Static")
(7) >>> app.Replace.Cancel.click()
(8) >>> app.UntitledNotepad.Edit.type_keys("Hi from Python interactive prompt %s" % str(dir()), with_spaces = True)
<pywinauto.controls.win32_controls.EditWrapper object at 0x00DDC2D0>
(9) >>> app.UntitledNotepad.menu_select("File -> Exit")
(10) >>> app.Notepad.DontSave.click()
>>>
导入pywinauto.application模块(通常是您需要直接导入的唯一模块)
创建一个Application实例。 对该应用程序的所有访问都是通过该对象完成的。
我们在步骤2中创建了一个Application实例,但是我们没有提供它所引用的Windows应用程序的任何信息。 通过使用start()方法,我们执行该应用程序并将其连接到Application实例应用程序。
在记事本对话框周围绘制一个绿色矩形 - 这样我们就知道我们有正确的窗口。
从应用程序所连接的应用程序的“记事本”对话框的“编辑”菜单中选择“替换”项。 此操作将显示“替换”对话框。
在“替换”对话框上打印控件的标识符,例如,“替换”对话框中的第一个编辑控件可以通过以下任何标识符引用:
app.Replace.Edit app.Replace.Edit0 app.Replace.Edit1 app.FindwhatEdit
最后一个是让用户在阅读脚本后最好了解脚本的功能。
关闭“替换”对话框。 (在脚本文件中,使用close_click()而不是click()更安全,因为close_click()会等待一段时间以给窗口时间关闭对话框。)
让我们在记事本文本区域中键入一些文本。 如果没有
with_spaces
参数,则不会输入空格。 请参阅SendKeys的文档,了解此方法,因为它是SendKeys的一个薄包装器。要求退出记事本
我们将被询问是否要保存 - 单击“否”按钮。
How To’s¶
How to specify a usable Application instance¶
Application()
实例是与您自动化的应用程序的所有工作的联系点。 因此,Application实例需要连接到进程。 有两种方法可以做到这一点:
start(self, cmd_line, timeout=app_start_timeout) # instance method:
or:
connect(self, **kwargs) # instance method:
start()
在应用程序未运行时使用,您需要启动它。 以下列方式使用它:
app = Application().start(r"c:\path\to\your\application -a -n -y --arguments")
timeout参数是可选的,只有在应用程序需要很长时间才能启动时才需要使用它。
当需要自动化的程序已经启动时,使用connect()
。 要指定已在运行的应用程序,您需要指定以下之一:
process: | 应用程序的进程ID,例如 app = Application().connect(process=2341)
|
---|---|
handle: | 应用程序窗口的窗口句柄,例如, app = Application().connect(handle=0x010f0c)
|
path: | 进程的可执行文件的路径( app = Application().connect(path=r"c:\windows\system32\notepad.exe")
|
或者指定窗口的参数的任意组合,这些参数将传递给pywinauto.findwindows.find_elements()
函数。 e.g.
app = Application().connect(title_re=".*Notepad", class_name="Notepad")
注意:在使用connect *()之前,应用程序必须准备就绪。 在start()之后找不到应用程序时没有超时或重试。 因此,如果您在pywinauto之外启动应用程序,则需要睡眠或编程等待循环以等待应用程序完全启动。
How to specify a dialog of the application¶
一旦应用程序实例知道它连接到哪个应用程序,就需要指定要处理的对话框。
有很多不同的方法可以做到这一点。 最常见的是使用项目或属性访问权来根据其标题选择对话框。 e.g
dlg = app.Notepad
or equivalently
dlg = app['Notepad']
下一个最简单的方法是要求top_window()
,例如
dlg = app.top_window()
这将返回具有应用程序顶级窗口的最高Z顺序的窗口。
注意:目前这是相当未经测试的,所以我不确定它是否会返回正确的窗口。 它绝对是应用程序的顶级窗口 - 它可能不是Z-Order中最高的窗口。
如果这不是足够的控制,那么你可以使用与传递给findwindows.find_windows()
相同的参数,例如
dlg = app.window(title_re="Page Setup", class_name="#32770")
最后,你可以使用最多的控制权
dialogs = app.windows()
这将返回应用程序的所有可见,启用的顶级窗口的列表。 然后,您可以使用handleprops
模块中的一些方法选择所需的对话框。 一旦掌握了所需的手柄,就可以使用
app.window(handle=win)
注意:如果对话框的标题很长 - 那么输入的属性访问可能会很长,在这种情况下通常更容易使用
app.window(title_re=".*Part of Title.*")
How to specify a control on a dialog¶
有许多方法可以指定控件,最简单的方法是
app.dlg.control app['dlg']['control']
The 2nd is better for non English OS’s where you need to pass unicode
strings e.g. app[u'your dlg title'][u'your ctrl title']
该代码根据以下内容为每个控件构建多个标识符:
- title
- friendly class
- title + friendly class
如果控件的标题文本为空(删除非char字符后),则不使用此文本。 相反,我们寻找控件上方和右侧最接近的标题文本。 并附上the friendly class。 So the list becomes
- friendly class
- closest text + friendly class
一旦为对话框中的所有控件创建了一组标识符,我们就消除它们的歧义。
use the WindowSpecification.print_control_identifiers() method
- e.g.
app.YourDialog.print_control_identifiers()
- Sample output
Button - Paper (L1075, T394, R1411, B485) 'PaperGroupBox' 'Paper' 'GroupBox' Static - Si&ze: (L1087, T420, R1141, B433) 'SizeStatic' 'Static' 'Size' ComboBox - (L1159, T418, R1399, B439) 'ComboBox' 'SizeComboBox' Static - &Source: (L1087, T454, R1141, B467) 'Source' 'Static' 'SourceStatic' ComboBox - (L1159, T449, R1399, B470) 'ComboBox' 'SourceComboBox' Button - Orientation (L1075, T493, R1171, B584) 'GroupBox' 'Orientation' 'OrientationGroupBox' Button - P&ortrait (L1087, T514, R1165, B534) 'Portrait' 'RadioButton' 'PortraitRadioButton' Button - L&andscape (L1087, T548, R1165, B568) 'RadioButton' 'LandscapeRadioButton' 'Landscape' Button - Margins (inches) (L1183, T493, R1411, B584) 'Marginsinches' 'MarginsinchesGroupBox' 'GroupBox' Static - &Left: (L1195, T519, R1243, B532) 'LeftStatic' 'Static' 'Left' Edit - (L1243, T514, R1285, B534) 'Edit' 'LeftEdit' Static - &Right: (L1309, T519, R1357, B532) 'Right' 'Static' 'RightStatic' Edit - (L1357, T514, R1399, B534) 'Edit' 'RightEdit' Static - &Top: (L1195, T550, R1243, B563) 'Top' 'Static' 'TopStatic' Edit - (L1243, T548, R1285, B568) 'Edit' 'TopEdit' Static - &Bottom: (L1309, T550, R1357, B563) 'BottomStatic' 'Static' 'Bottom' Edit - (L1357, T548, R1399, B568) 'Edit' 'BottomEdit' Static - &Header: (L1075, T600, R1119, B613) 'Header' 'Static' 'HeaderStatic' Edit - (L1147, T599, R1408, B619) 'Edit' 'TopEdit' Static - &Footer: (L1075, T631, R1119, B644) 'FooterStatic' 'Static' 'Footer' Edit - (L1147, T630, R1408, B650) 'Edit' 'FooterEdit' Button - OK (L1348, T664, R1423, B687) 'Button' 'OK' 'OKButton' Button - Cancel (L1429, T664, R1504, B687) 'Cancel' 'Button' 'CancelButton' Button - &Printer... (L1510, T664, R1585, B687) 'Button' 'Printer' 'PrinterButton' Button - Preview (L1423, T394, R1585, B651) 'Preview' 'GroupBox' 'PreviewGroupBox' Static - (L1458, T456, R1549, B586) 'PreviewStatic' 'Static' Static - (L1549, T464, R1557, B594) 'PreviewStatic' 'Static' Static - (L1466, T586, R1557, B594) 'Static' 'BottomStatic'
此示例取自test_application.py
注意此方法打印的标识符已经过使标识符唯一的过程。 因此,如果您有两个编辑框,则它们的标识符中都会列出“Edit”。 实际上,虽然第一个可以被称为“Edit”,“Edit0”,“Edit1”和第二个应该被称为“Edit2”
Note You do not have to be exact!. 假设我们从上面的例子中获取一个实例
Button - Margins (inches) (L1183, T493, R1411, B584) 'Marginsinches' 'MarginsinchesGroupBox' 'GroupBox'
让我们说你不喜欢这些
GroupBox
- 太通用了,它可以是任何组合框Marginsinches
和MarginsinchesGroupBox
- 这些只是看起来不错,省略'inches'部分会更好
Well you CAN! 代码与您对照对话框中所有可用标识符使用的标识符进行最佳匹配。
例如,如果您进入调试器,您可以看到如何使用不同的标识符
(Pdb) print app.PageSetup.Margins.window_text() Margins (inches) (Pdb) print app.PageSetup.MarginsGroupBox.window_text() Margins (inches)
这也将迎合拼写错误。 虽然你仍然需要小心,好像在对话框中有2个类似的标识符,你使用的拼写错误可能与你想到的另一个控件更相似。
如何将pywinauto与英语¶以外的应用程序语言一起使用
由于Python不支持代码中的unicode标识符,因此您无法使用属性访问来引用控件,因此您必须使用项访问权或对window()
进行显式调用。
So instead of writing
app.dialog_ident.control_ident.click()
You would have to write
app['dialog_ident']['control_ident'].click()
或者明确地使用window()
app.window(title_re="NonAsciiCharacters").window(title="MoreNonAsciiCharacters").click()
To see an example of this check examples\misc_examples.py get_info()
如何处理未按预期响应的控件(例如OwnerDraw控件)¶
某些控件(尤其是Ownerdrawn控件)不会按预期响应事件。 例如,如果您查看任何HLP文件并转到“索引”选项卡(单击“搜索”按钮),您将看到一个列表框。 在此运行Spy或Winspector将向您显示它确实是一个列表框 - 但它是ownerdrawn。 这意味着开发人员告诉Windows他们将覆盖项目的显示方式并自行完成。 在这种情况下,他们已经使它无法检索字符串:-(。
那导致什么问题呢?
app.HelpTopics.ListBox.texts() # 1 app.HelpTopics.ListBox.select("ItemInList") # 2
- 将返回一个空字符串列表,这一切都意味着pywinauto无法获取列表框中的字符串
- 这将因IndexError而失败,因为ListBox的select(string)方法在文本中查找项目以了解它应该选择的项目的索引。
以下解决方法将适用于此控件
app.HelpTopics.ListBox.select(1)
这将选择列表框中的第二项,因为它不是字符串查找,它可以正常工作。
不幸的是,即便这样也无济于事。 开发人员可以使控件不响应Select等标准事件。 在这种情况下,您可以在列表框中选择项目的唯一方法是使用TypeKeys()的键盘模拟。
这允许您向控件发送任何击键。 所以要选择你要使用的第3个项目
app.Helptopics.ListBox1.type_keys("{HOME}{DOWN 2}{ENTER}")
{HOME}
将确保突出显示第一个项目。{DOWN 2}
然后将亮点向下移动两项{ENTER}
将选择突出显示的项目
如果您的应用程序广泛使用类似的控件类型,那么您可以通过从ListBox派生新类来更轻松地使用它,这可以使用有关您的特定应用程序的额外知识。 例如,在WinHelp示例中,每次在列表视图中突出显示某个项目时,其文本都会插入到列表上方的Edit控件中,并且您可以从那里获取该项目的文本,例如:
# print the text of the item currently selected in the list box # (as long as you are not typing into the Edit control!) print app.HelpTopics.Edit.texts()[1]
如何访问系统托盘(又名SysTray,又名“Notification Area”)¶
在时钟附近有表示正在运行的应用程序的图标,该区域通常被称为“系统托盘”。 事实上,这个区域有许多不同的windows/controls装置。 包含图标的控件实际上是一个工具栏。 它是一个带有TrayNotifyWnd类的窗口中的Pager控件的子节点,它位于另一个带有Shell_TrayWnd类的窗口中,所有这些窗口都是正在运行的Explorer实例的一部分。 谢天谢地,你不需要记住所有这些:-)。
需要记住的重要一点是,您正在“Explorer.exe”应用程序中查找一个窗口“Shell_TrayWnd”,该窗口具有标题为“通知区域”的工具栏控件。
解决此问题的一种方法是执行以下操作
import pywinauto.application app = pywinauto.application.Application().connect(path="explorer") systray_icons = app.ShellTrayWnd.NotificationAreaToolbar
任务栏模块提供对系统托盘的初步访问。
它定义了以下变量:
explorer_app: | 定义连接到正在运行的资源管理器的Application()对象。 您可能不需要直接使用它。 |
---|---|
TaskBar: | 任务栏的句柄(包含“开始”按钮,QuickLaunch图标,正在运行的任务等的栏) |
StartButton: | “Start me up”:-)我想你可能知道这是什么! |
QuickLaunch: | 带有快速启动图标的工具栏 |
SystemTray: | 包含时钟和系统托盘图标的窗口 |
Clock: | 时钟 |
SystemTrayIcons: | |
工具栏代表系统托盘图标 | |
RunningApplications: | |
工具栏代表正在运行的应用程序 |
我还在模块中提供了两个可用于单击系统托盘图标的功能:
ClickSystemTrayIcon(button) : | |
---|---|
您可以使用此按钮左键单击系统托盘中的可见图标。 我不得不专门说明可见图标,因为可能有很多看不见的图标显然无法点击。 按钮可以是任何整数。 如果指定3则会找到并单击第3个可见按钮。 (现在几乎没有执行错误检查,但将来很可能会移动/重命名此方法。) | |
RightClickSystemTrayIcon(button) : | |
与ClickSytemTrayIcon 类似,但执行右键单击。 |
通常,当您单击/右键单击图标时,会出现一个弹出菜单。 此时要记住的是弹出菜单是应用程序的一部分,自动化而不是资源管理器的一部分。
e.g.
# connect to outlook outlook = Application.connect(path='outlook.exe') # click on Outlook's icon taskbar.ClickSystemTrayIcon("Microsoft Outlook") # Select an item in the popup menu outlook.PopupMenu.Menu().get_menu_path("Cancel Server Request")[0].click()
等待长时间操作¶
GUI应用程序行为通常不稳定,您的脚本需要等待,直到出现新窗口或关闭/隐藏现有窗口。 pywinauto可以隐式等待对话框初始化(使用默认超时)。 很少有方法/功能可以帮助您使代码更容易,更可靠。
Application methods¶
- wait_cpu_usage_lower (new in pywinauto 0.5.2, renamed in 0.6.0)
此方法对于允许在另一个线程中进行延迟初始化的多线程接口非常有用,同时GUI响应并且所有控件都已存在且可以使用。 所以等待特定的窗口存在/状态是没用的。 在这种情况下,整个过程的CPU使用率表明任务计算尚未完成。
Example:
app.wait_cpu_usage_lower(threshold=5) # wait until CPU usage is lower than 5%
WindowSpecification方法¶
这些方法适用于所有控件。
There is an example containing long waits: install script for 7zip 9.20 x64.
WindowSpecification
对象不一定与现有窗口/控件相关。
这只是一个描述,即搜索窗口的几个标准。 wait
方法(如果没有引发任何异常)可以保证目标控件存在,甚至可见,启用和/或激活。
Functions in timings
module¶
还有一些对任何Python代码都有用的低级方法。
如果每个函数调用都应该具有时序控制,也可以使用装饰器pywinauto.timings.always_wait_until()
和pywinauto.timings.always_wait_until_passes()
。
# call ensure_text_changed(ctrl) every 2 sec until it's passed or timeout (4 sec) is expired
@always_wait_until_passes(4, 2)
def ensure_text_changed(ctrl):
if previous_text == ctrl.window_text():
raise ValueError('The ctrl text remains the same while change is expected')
每种不同控制类型可用的方法¶
Windows有许多控件,按钮,列表等
All Controls¶
These functions are aviailable to all controls.
- capture_as_image
- click
- click_input
- close
- close_click
- debug_message
- double_click
- double_click_input
- drag_mouse
- draw_outline
- get_focus
- get_show_state
- maximize
- menu_select
- minimize
- move_mouse
- move_window
- notify_menu_select
- notify_parent
- press_mouse
- press_mouse_input
- release_mouse
- release_mouse_input
- restore
- right_click
- right_click_input
- send_message
- send_message_timeout
- set_focus
- set_window_text
- type_keys
- Children
- Class
- ClientRect
- ClientRects
- ContextHelpID
- ControlID
- ExStyle
- Font
- Fonts
- FriendlyClassName
- GetProperties
- HasExStyle
- HasStyle
- IsChild
- IsDialog
- IsEnabled
- IsUnicode
- IsVisible
- Menu
- MenuItem
- MenuItems
- Owner
- Parent
- PopupWindow
- ProcessID
- Rectangle
- Style
- Texts
- TopLevelParent
- UserData
- VerifyActionable
- VerifyEnabled
- VerifyVisible
- WindowText
Button, CheckBox, RadioButton, GroupBox¶
ComboBox¶
Edit¶
ListBox¶
ListView¶
- ListViewWrapper.Check
- ListViewWrapper.ColumnCount
- ListViewWrapper.Columns
- ListViewWrapper.ColumnWidths
- ListViewWrapper.GetColumn
- ListViewWrapper.GetHeaderControl
- ListViewWrapper.GetItem
- ListViewWrapper.GetSelectedCount
- ListViewWrapper.IsChecked
- ListViewWrapper.IsFocused
- ListViewWrapper.IsSelected
- ListViewWrapper.ItemCount
- ListViewWrapper.Items
- ListViewWrapper.Select
- ListViewWrapper.Deselect
- ListViewWrapper.UnCheck
Static¶
(no extra visible methods)
StatusBar¶
TabControl¶
Credits¶
(listed in reverse chronological order)
Vasily Ryabov,Valentin Kroupkin,Alexander Rumyantsev - MS UI Automation后端实现
Ivan Magazinnik - mouse/keyboard input emulation on Linux
Maxim Samokhvalov - initial implementation of hooks.py module
Intel Corporation - Vasily Ryabov revived and maintained the project during his work at Intel (pywinauto 0.5.x)
Valentin Kroupkin (airelil) - continuous integration (AppVeyor), many unit tests improvements (pywinauto 0.5.x)
Michael Herrmann - bug fixes, project maintenance (0.4.x)
Raghav - idea with using metaclass for finding wrapper
Daisuke Yamashita - Bugs/suggestions for 2.5 that MenuWrapper.GetProperties() returns a list rather then a dict
Dalius Dobravolskas - Help on the forums and prompted major improvements on the wait* functionality
Jeff Winkler - Early encouragement, creation of screencasts
Stefaan Himpe - Lots of speed and stability improvements early on
Dev Notes¶
文件布局¶
# used by just about everything (and considered a block!) win32defines.py win32functions.py win32structures.py
# Find windows and their attributes findwindows.py handleprops.py
# wrap windows, get extra info for particular controls # set the friendly class name controlscommon_controls.py controlscontrolactions.py controlshwndwrapper.py controlswin32_controls.py
# currently depends on the Friendly class name # probably needs to be refactored to make it independent of controls! # maybe move that stuff to _application_? findbestmatch.py # currently depends on controls!
controlactions.py
testsallcontrols.py testsasianhotkey.py testscomboboxdroppedheight.py testscomparetoreffont.py testsleadtrailspaces.py testsmiscvalues.py testsmissalignment.py testsmissingextrastring.py testsoverlapping.py testsrepeatedhotkey.py teststranslation.py teststruncation.py
controlproperties.py
xml_helpers.py
FindDialog.py PyDlgCheckerWrapper.py
application.py test_application.py
Best matching¶
difflib提供此支持对于菜单,我们很简单地匹配菜单项的文本。 对于控件,故事更复杂,因为我们想要匹配以下内容:
- Control text if it exists
- Friendly Class name
- Control text + Friendly class name (if control text exists)
- (Possibly) closest static + FriendlyClassName
- e.g.
- FindWhatCombo, ComboBox1,
- or
- Text, TextRiadio, RadioButton2
- 控件本身知道应该引用什么
- 需要消除对话框中所有控件的歧义
- 那我们需要匹配
ATTRIBUTE RESOLUTION¶
Thinking again... app.dlg.control
- TWO LEVELS
- application.member (Python resolves)
- 应用程序对象的属性
- application.dialog
- 对话框参考
- THREE LEVELS
- application.member.attr (Python resolves)
- 前一个成员的另一个属性
- application.dialog.member
- 对话框对象的成员
- application.dialog.control
- 对话框的控件
- FOUR LEVELS (leaving out Python resolved)
- application.dialog.member.member
- application.dialog.control.member
DELAYED RESOLUTION FOR SUCCESS Taking the example
app.dlg.control.action()
如果我们省略语法和编程错误,仍然有很多原因导致它失败。
可能找不到dlg可能无法找到控件dlg或控件可能被禁用
可以在错误的对话框中找到对话框和控件(例如在记事本中,您可以使用“确定”按钮调出2个“页面设置”对话框)
一种解决方案就是在尝试找到每个新对话框之前添加一个“睡眠”(以确保它在那里并准备就绪) - 但这将意味着许多不必要的等待。
- So the solution I have tried is:
- 在最近的可能时间执行完整的属性访问解析
- 如果失败则等待再试一次
- 在指定的超时失败后引发原始异常。
这意味着在正常情况下,您没有不必要的等待 - 并且在失败的情况下 - 您仍然会收到错误的异常。
还等待尽可能晚地解决问题会阻止路径的早期部分成功的错误 - 但找到错误的项目。
例如,如果在记事本中找到页面设置对话框
# if this runs too quickly it actually finds the current page setup dialog # before the next dialog opens, but that dialog does not have a Properties # button - so an error is raised. # because we re-run the resolution from the start we find the new pagesetup dialog. app.PageSetup.Properties.Click()
WRITING TO DIALOGS¶
我们需要一种确保对话框处于活动状态而无需访问控件的方法。 e.g.
app.MainWin.MenuSelect("Something That->Loads a Dialog")
app.Dlg._write("dlg.xml")
or a harder problem:
app.PageSetup.Printer.Click()
app.PageSetup._write("pagesetup.xml")
在第二个示例中,很难确定是否显示了正确的页面设置对话框。
唯一确定的方法是检查某些控制(ID,类,文本,等等)是否存在 - 但是不必处理那些是很好的:-(
Another less declarative (more magic?) 是扫描可用的窗口/控件列表,如果它们没有更改,则接受显示正确的窗口/控件。
在测试和使用XML文件时,我们应该使用它们以确保我们有正确的对话框(通过使用类/ ID)
PYWINAUTO TODO’s¶
确保为所有未记录的方法/函数添加文档字符串
检查测试的覆盖范围并努力增加测试。
添加SendInput单击方法的测试
使用FuzzyDict实现findbestmatch。
找到一种以更好的方式处理应用程序数据的方法。 目前,如果有人甚至添加了对print_control_identifiers()的调用,它将破坏匹配算法!
需要移动检查控件是__init__方法中的所有者拉出/位图控件,还有自己的方法,比如IsNormallyRendered()(为什么?)
举例说明如何使用Tray Window
修复ToolbarWrapper.PressButton()似乎不起作用(发现在IE示例脚本上工作)
也许提供一个选项,以便可以使用以下命令运行脚本:
pywinauto.exe yourscript.py
这可以通过创建一个导入脚本的Py2exe包装器(并可选地调用特定的函数?)来实现。
这样pywinauto可以在没有安装python的情况下使用(无论这是一个很大的要求,我不知道,因为自动化语言无论如何都是python!
消息陷阱 - 如何处理不需要的消息框弹出?
- Wait for an Exception then handle it there
- set a trap waiting for a specific dialog
- 在调用窗口规范时,如果我们找不到窗口,那么我们可以快速浏览可用的指定陷阱以查看是否有任何陷阱 - 如果他们这样做我们可以运行相关的操作 - 然后再次尝试我们的原始对话框
处理添加引用控件(因为它们应该是用于查找窗口的控件)
找到一个变量的引用名,例如,在Dialog._write()中我们可以知道调用_write的变量名(我们不必重复XML文件名!)
如果我们在按钮单击控制后删除延迟然后尝试连续关闭两个对话框可能会失败,因为第一个对话框尚未关闭,第二个可能具有相似的标题和相同的关闭按钮,例如PageSetup.OK.Click() ,PageSetup2.OK.Click()。 一个可能的解决方案可能是在应用程序中保留一个窗口缓存,并且没有两个不同的对话框标识符(在这种情况下为PageSetup和PageSetup2)可以具有相同的句柄 - 因此当我们调用PageSetup2时返回PageSetup的句柄会失败(和我们会按惯例等待,直到成功或超时)。
使用以下任何一项进行调查
- BringWindowToTop:在图像捕获之前可能需要
- GetTopWindow:捕获后可能重新设置顶部窗口?
- EnumThreadWindows
- GetGUIThreadInfo
使用上下文(右键单击)菜单可以轻松使用
进一步支持.NET控件并下载/创建测试.NET应用程序
看看支持Sytem托盘(例如右键单击图标)
提供SystemTray类(可能是单例)
查看单击和文本输入 - 也许使用SendInput
支持Up-Down控件和其他常用控件
找出control.item.action()或control.action(item)是否更好
创建一个Recorder以可视化创建测试
LOW PRIORITY
创建一个类,可以轻松处理单个窗口(例如,没有应用程序)
允许应用程序在不同的线程中启动,因此我们不会锁定
- 这已经完成了 - 问题是如果某些消息有指针就无法跨进程发送(因此我们需要发送一条同步消息,等待其他进程在返回之前做出响应)
- 但我想有可能创建一个发送这些消息的线程?
从HwndWrapper中解放代码 - 除了handleprops中提供的内容之外,几乎没有这些添加内容。 这是必需的主要原因是FriendlyClassName。 所以我需要看看是否可以将其转移到其他地方。
这样做可能会使heirarchy变得相当扁平并减少对各种包的依赖性
需要将菜单项设置为类,而不是Dlg.MenuSelect,我们应该这样做
dlg.Menu("blah->blah").Select()
or even
dlg.Menu.Blah.Blah.Select()
为此,我们需要更改菜单的检索方式 - 而不是在开始时获取所有菜单项 - 然后我们只需获得所请求的级别。
这也可以实现这样的目标
dlg.Menu.Blah.Blah.IsChecked() IsEnabled(), etc
CLOSED (in some way or the other)¶
单击后允许延迟删除。 目前需要这样做的主要原因是因为如果你关闭一个对话框,然后立即尝试对父进行操作,它可能还没有激活 - 所以需要延迟才能使它变为活动状态。 要解决此问题,我们可能需要在对话框上调用操作时添加更多魔法,例如:在ActionDialog的属性访问上执行以下操作:
- 检查它是否是一个动作
- 如果未启用,请稍等一下
- 如果是,那么稍等一下再试一次
- 重复,直到成功或超时
需要解决的主要问题是你不希望同时发生这些等待中的两个(所以在1级的函数中等待,而在另一个函数调用的函数中等待另一次 - 因为这意味着那里当嵌套函数的超时达到调用func尝试成功的次数时,将是一个非常长的延迟!)
通过最近的静态(或周围的组框?)添加引用
需要模块化common_controls的方法,因为目前它们太单一了。
完成从IE保存页面的示例
在选择菜单项之前,我无法弄清楚如何可靠地检查菜单项是否已启用的文档。 (Probably FIXED NOW!)
例如,如果您尝试单击视图,则在Media Player中为示例 理论上应该使用MF_DISABLED和MF_GRAYED - 但我发现这些都没有更新(至少对于Media Player),直到它们被删除。
实现一个opional timing / config模块,以便可以自定义所有时序
Change Log¶
0.6.5 Handling Privileges, AutomationID for Win32 etc.¶
30-July-2018
- Enhancements:
- 检查目标应用程序和Python进程的管理员权限。 这允许在窗口消息不起作用时检测案例。
- 为“win32”后端添加
automation_id
和control_type
属性(对WinForms最有用)。 正确的child_window()关键字是auto_id
和control_type
。 - 切换pypiwin32依赖于pywin32再次成为官方。
- 新生成器
iter_children()
和iter_descendants()
。 - 将方法
is_checked()
添加到“win32”复选框。
- Bug Fixes:
- Method
Application().connect(...)
works better withtimeout
argument. - Fix
.set_focus()
for “uia” backend including minimized window case (issue #443). maximize()/minimize()
methods can be chained now.- Fix passing keyword arguments to a function for decorators
@always_wait_until_passes
and@always_wait_until
. - Use correct types conversion for WaitGuiThreadIdle (issue #497).
- Fix reporting code coverage on Linux.
- Use .format() for logging BaseWrapper actions (issue #471).
- Print warning in case binary type is not determined (issue #387).
- Method
0.6.4 NULL pointer access fix and enhancements¶
21-January-2018
- Bug Fixes:
- Final fix for
ValueError: NULL COM pointer access
.
- Final fix for
- Enhancements:
Multi-threading mode (MTA) for comtypes is enabled by default, if it’s not initialized by another library before importing pywinauto.
Method
get_value()
has been added to EditWrapper in UIA backend.Method
scroll()
has been added for all UIA controls which have ScrollPattern implemented.Added methods
is_minimized/is_maximized/is_normal/get_show_state
for UIAWrapper.Added handling in-place controls inside ListView control and (row, column) indexing in a grid-like table mode. Examples:
auto_detected_ctrl = list_view.get_item(0).inplace_control() combo = list_view.get_item(1,1).inplace_control("ComboBox") combo.select("Item name") edit = list_view.get_item(3,4).inplace_control("Edit") edit.type_keys("some text{ENTER}", set_foreground=False) dt_picker = list_view.get_item(2,0).inplace_control("DateTimePicker")
0.6.3 A lot of improvements and some optimizations¶
- 03-July-2017
- Improved string representation for all wrapper objects. Thanks airelil!
- Fixed several sporadic crashes for
backend="uia"
. - Fixed several bugs in
wait/wait_not
methods:- Method
wait('exists')
doesn’t work forbackend="uia"
. Thanks maollm! - Methods
wait/wait_not
take ~ default time (5 sec.) instead of customized timeout like 1 sec.
- Method
depth
param can used in aWindowSpecification
now.depth=1
means this control,depth=2
means immediate children only and so on (aligned withprint_control_identifiers
method). Thanks dmitrykazanbaev!- Significantly improved sending keys to an inactive window silently. Special thanks for antonlarin! Now 2 methods are available:
send_chars
is supposed to send character input (this includes{Enter}
,{Tab}
,{Backspace}
) without Alt/Shift/Ctrl modifiers.send_keystrokes
is for key input (including key combinations with Alt/Shift/Ctrl modifiers).
- Method
Application().connect(path='your.exe')
uses default timeoutTimings.app_connect_timeout
. It can accepttimeout
andretry_interval
keyword arguments. Thanks daniil-kukushkin! - Method
print_control_identifiers
is more consistent and minimum 2x faster now! Thanks cetygamer! - Fixed subclassing
Application
with your own methods. Thanks efremovd! - Param
work_dir
can be used inApplication().start(...)
. Thanks efremovd! - Class
Application
has been enriched with methodsis_process_running()
andwait_for_process_exit()
. Thanks efremovd! - Module
timings
usestime.clock()
for Python 2.x andtime.perf_counter()
for Python 3.x so that accident system time change can’t affect on your script behavior. Thanks airelil! - Added WireShark example. Thanks ViktorRoy94!
- Now
print_control_identifiers()
can dump UI elements tree to a file. Thanks sovrasov! - Improved logging actions for
backend="uia"
, extended example for MS Paint. Thanks ArtemSkrebkov! - Extended
CalendarWrapper
forbackend="win32"
with these methods:get_month_delta
,set_month_delta
andget_month_range
. Thanks Nikita-K! - Added method
legacy_properties()
toUIAWrapper
. Thanks AsyaPronina! - Improved VB6 ListView detection for
backend="win32"
. Thanks KirillMoizik! - Fixed 64-bit specific bug in
TreeViewWrapper
forbackend="win32"
(argument 4: <type 'exceptions.OverflowError'>: long int too long to convert
).
0.6.2 More bug fixes¶
- 28-February-2017
- Several bugs were fixed:
- Maximized window is always resized (restored) when calling
set_focus()
. - AttributeError: type object ‘_CustomLogger’ has no attribute ‘disable’.
print_control_identifiers()
gets bytes string on Python 3.x.- Importing pywinauto causes debug messages to appear twice.
- Maximized window is always resized (restored) when calling
- Improved click methods behaviour for Win32 ListView and TreeView:
ensure_visible()
is called inside before the click. - Made
taskbar.SystemTrayIcons
localization friendly.
- Several bugs were fixed:
0.6.1 Bug fixes and optimizations for UI Automation and beyond¶
- 08-February-2017
win32_hooks
module is well tested and more reliable now. See detailed example.Fixed several bugs and crashes here and there.
- Crash when ctrl.window_text() becomes None at the right moment. Thanks mborus!
HwndWrapper.set_focus()
fails when used via interpreter. Thanks Matthew Kennerly!
- Fix LoadLibrary call error on just released Python 2.7.13. Thanks Kirill Moizik!
- AttributeError: WindowSpecification class has no ‘CPUUsage’ method.
comtypes
prints a lot of warnings atimport pywinauto
.- Methods
is_dialog()
andrestore()
are missed for UIA backend. - Method
print_control_identifiers()
crashes on some applications with Unicode symbols. - Installation by
python setup.py install
may fail if pyWin32 dependency was installed manually. - Bug in resolving attributes: ‘UIAWrapper’ object has no attribute ‘Menu’ for
dlg = app.Custom.Menu
- Method
send_chars()
can now send{ENTER}
to some applications. Thanks Max Bolingbroke!
Searching UI elements is faster now especially if you use
control_type
orauto_id
in a WindowSpecification. MethodApplication.kill()
is also optimized in many cases.Added an example for Win10 Calculator.
0.6.0 Introduce MS UI Automation support and many more improvements¶
- 30-October-2016
- This big release introduces MS UI Automation (UIA) support:
- Just start from
app = Application(backend='uia').start('your_app.exe')
. - Supported controls: Menu, Button/CheckBox/RadioButton, ComboBox, Edit, Tab control, List (ListView), DataGrid, Tree, Toolbar, Tooltip, Slider.
- Just start from
- Documentation is built continuously now on ReadTheDocs. See also improved Getting Started Guide.
- New multi-backend architecture makes implementation of new platforms support
easier in the future. The minimal set for new backend includes its name and
two classes inherited from
element_info.ElementInfo
and frompywinauto.base_wrapper.BaseWrapper
. New backend must be registered by functionpywinauto.backend.register()
. - Code style is much closer to PEP8: i.e.
click_input
should be used instead ofClickInput
. - Initial implementation of the
hooks
module. Keyboard and mouse event handlers can be registered in the system. It was inspired by pyHook, pyhk, pyhooked and similar modules, but re-written from scratch. Thanks for Max Samokhvalov! The fork of thehooks
module is used in pyhooked 0.8 by Ethan Smith. - A lot of small improvements are not counted here.
- This big release introduces MS UI Automation (UIA) support:
0.5.2 Improve ListView, new methods for CPU usage, DPI awareness¶
07-September-2015
- New Application methods:
CPUUsage
returns CPU usage as a percent (float number),WaitCPUUsageLower
waits until the connected process’ CPU usage is lower than a specified value (2.5% by default).- A new class
_listview_item
. It is very similar to_treeview_element
.- Add DPI awareness API support (Win8+). It allows correct work when all fonts are scaled at 125%, 150% etc (globally or per monitor).
- “Tools overview” section in docs.
- Fix number of bugs:
TreeViewWrapper.Select
doesn’t work when the control is not in focus.TabControlWrapper.Select
doesn’t work in case of TCS_BUTTONS style set.ListViewWrapper
methodsCheck/UnCheck
are fixed.- Toolbar button: incorrect access by a tooltip text.
- Warning “Cannot retrieve text length for handle” uses print() instead of actionlogger.
ClientToScreen
method doesn’t return a value (modifying mutable argument is not good practice).
0.5.1 Several fixes, more tests¶
13-July-2015
- Resolve pip issues
- Warn user about mismatched Python/application bitness (64-bit Python should be used for 64-bit application and 32-bit Python is for 32-bit app)
- Add “TCheckBox” class name to ButtonWrapper detection list
- Fix
DebugMessage
method- Disable logging (actionlogger.py) by default, provide shortcuts:
actionlogger.enable()
andactionlogger.disable()
. For those who are familiar with standardlogging
module there’s methodactionlogger.set_level(level)
0.5.0 64-bit Py2/Py3 compatibility¶
30-June-2015
- 64-bit Python and 64-bit apps support (but 32-bit Python is recommended for 32-bit apps)
- Python 2.x/3.x compatibility
- Added pyWin32 dependency (silent install by pip for 2.7 and 3.1+)
- Improvements for Toolbar, TreeView, UpDown and DateTimePicker wrappers
- Improved
best_match
algorithm allows names likeToolbarFile
- Clicks can be performed with pressed Ctrl or Shift
- Drag-n-drop and scrolling methods (DragMouse, DragMouseInput, MouseWheelInput)
- Improved menu support: handling OWNERDRAW menu items; access by command_id (like
$23453
)- Resolved issues with py2exe and cx_freeze
RemoteMemoryBlock
can now detect memory corruption by checking guard signature- Upgraded
taskbar
modulesysinfo
module for checking 32-bit or 64-bit OS and Pythonset_foreground
flag inTypeKeys
method for typing into in-place controls- flags
create_new_console
andwait_for_idle
inApplication.start
method
0.4.0 Various cleanup and bug fixes¶
03-April-2010
- Gracefully Handle dir() calls on Application or WindowSpecification objects (which used hang for a while as these classes would search for windows matching __members__, __methods__ and __bases__). The code now checks for any attribute that starts with ‘__’ and ends with ‘__’ and raises AttributeError immediately. Thanks to Sebastian Haase for raising this.
- Removed the reference to an Application object in WindowSpecification. It was not used in the class and made the class harder to use. WindowSpecification is now more useful as a utility class.
- Add imports of application.WindowSpecification and application.Application to pywinauto.__init__.py so that these classes can be used more easily (without having to directly import pywinauto.application). Thanks again to Sebastian Haase.
- Added a function to empty the clipboard (thanks to Tocer on Sourceforge)
- Use ‘SendMessageTimeout’ to get the text of a window. (SendMessage will hang if the application is not processing messages)
- Fixed references to PIL.ImageGrab. PIL add’s it’s module directly to the module path, so it should just be referenced by ImageGrab and not PIL.ImageGrab.
- Use AttachThreadInput + PostMessage rather than SendMessageTimeout to send mouse clicks.
- Fix how timeout retry times are calculated in timings.WaitUntil() and timings.Wait
- Fixed some issues with application.Kill_() method, highlighted due to the changes in the HwndWrapper.Close() method.
- Fix writing images to XML. It was broken with updates to PIL that I had not followed. Changed the method of knowing if it is an image by checking for various attributes.
- Renamed WindowSpecification.(Ww)indow() to ChildWindow() and added deprecation messages for the other functions.
- Improved the tests (fixed test failures which were not pywinauto issues)
0.3.9 Experimental! New Sendkeys, and various fixes¶
27-November-2009
- Major change this release is that Sendkeys is no longer a requirement! A replacement that supports Unicode is included with pywinauto. (hopefully soon to be released as a standalone module). Please note - this is still quite untested so this release should be treated with some care..
- Made sure that default for WindowSpecification.Window_() was to look for non top level windows. The defaults in find_windows() had been changed previously and it now needed to be explicitly overridden.
- Fixed a missing reference to ‘win32defines’ when referencing WAIT_TIMEOUT another typo of false (changed to False)
- Removed the restriction to only get the active windows for the process, now it will be possible to get the active windows, even if a process is not specified. From http://msdn.microsoft.com/en-us/library/ms633506%28VS.85%29.aspx it gets the active window for the foreground thread.
- Hopefully improved Delphi TreeView and ListView handling (added window class names as supported window classes to the appropriate classes).
- Added support for running UI tests with reference controls. (requried for some localization tests)
- Various PyLint and PEP8 fixes made.
0.3.8 Collecting improvements from last 2 years¶
10-March-2009
- Fixed toolbar button pressing - This required for HwndWrapper.NotifyParent() to be updated (to accept a new ID parameter)
- Fixed a bug wherea listview without a column control would make pywinauto fail to capture the dialog.
- Converted documenation from Pudge generated to Sphinx Generated
- Added some baic support for Pager and Progress controls (no tests yet)
- Added some more VB ‘edit’ window classes
- Added some more VB ‘listbox’ window classes
- Added some more VB ‘button’ window classes
- Ensured that return value from ComboBoxWrapper.SelectedIndices is always a tuple (there was a bug where it would sometimes be a ctypes array)
- Changed default for finding windows to find disabled windows as well as enabled ones (previous was to find enabled windows only) (note this may impact scripts that relied on the previous setting i.e. in cases where two dialogs have the same title!)
- Much better handling of InvalidWindowHandle during automation runs. This could be raised when a closing window is still available when the automation was called, but is gone half way through whatever function was called.
- Made clicking more robust by adding a tiny wait between each SendMessageTimeout in _perform_click().
- Added attributes
can_be_label
andhas_title
toHwndWrapper
and subclasses to specify whether a control can act as a label for other controls, and whether the title should be used for identifying the control. If you have created your own HwndWrapper subclasses you may need to override the defaults.- Added a
control_id
parameter to find_windows which allows finding windows based off of their control id’s- Added a FriendlyClassName method to MenuItem
- Split up the functions for button truncation data
- Commented out code to get a new font if the font could not be recovered
- Moved code to get the control font from Truncation test to handleprops
- Added a function to get the string representation of the bug. (need to refactor PrintBugs at some point).
- Fixed a variable name (from fname -> font_attrib as fname was not a defined variable!)
- Forced some return values from MissingExtraString test to be Unicode
- Fixed the MiscValues test (converted to Unicode and removed some extraneous characters)
- Updated the path for all unittests
- Made two unit tests sligthly more robust and less dependent on computer/app settings
- Updated timing settings for unit tests
- Updated the examples to work in dev environment.
0.3.7 Merge of Wait changes and various bug fixes/improvements¶
10-April-2007
- Added Timings.WaitUntil() and Timings.WaitUntilPasses() which handle the various wait until something in the code. Also refactored existing waits to use these two methods.
- Fixed a major Handle leak in RemoteMemorBlock class (which is used extensively for ‘Common’ controls. I was using OpenHandle to open the process handle, but was not calling CloseHandle() for each corresponding OpenHandle().
- Added an active_() method to Application class to return the active window of the application.
- Added an ‘active’ option to WindowSpecification.Wait() and WaitNot().
- Some cleanup of the clipboard module. GetFormatName() was improved and GetData() made a little more robust.
- Added an option to findwindows.find_windows() to find only active windows (e.g. active_only = True). Default is False.
- Fixed a bug in the timings.Timings class - timing values are Now accessed through the class (Timings) and not through the intance (self).
- Updated ElementTree import in XMLHelpers so that it would work on Python 2.5 (where elementtree is a standard module) as well as other versions where ElementTree is a separate module.
- Enhanced Item selection for ListViews, TreeViews - it is now possible to pass strings and they will be searched for. More documentation is required though.
- Greatly enhanced Toolbar button clicking, selection, etc. Though more documentation is required.
- Added option to ClickInput() to allow mouse wheel movements to be made.
- menuwrapper.Menu.GetProperties() now returns a dict like all other GetProperties() methods. This dict for now only has one key ‘MenuItems’ which contains the list of menuitems (which had been the previous return value).
0.3.6b Changes not documented in 0.3.6 history¶
31-July-2006
- Fixed a bug in how findbestmatch.FindBestMatches was working. It would match against text when it should not!
- Updated how timings.Timings.Slow() worked, if any time setting was less then .2 after ‘slowing’ then set it to .2
0.3.6 Scrolling and Treview Item Clicking added¶
28-July-2006
- Added parameter to
_treeview_item.Rectangle()
to have an option to get the Text rectangle of the item. And defaulted to this. - Added
_treeview_item.Click()
method to make it easy to click on tree view items. - Fixed a bug in
TreeView.GetItem()
that was expanding items when it shouldn’t. - Added
HwndWrapper.Scroll()
method to allow scrolling. This is a very minimal implementation - and if the scrollbars are implemented as separate controls (rather then a property of a control - this will probably not work for you!). It works for Notepad and Paint - that is all I have tried so far. - Added a call to
HwndWrapper.SetFocus()
in_perform_click_input()
so that calls toHwndWrapper.ClickInput()
will make sure to click on the correct window.
0.3.5 Moved to Metaclass control wrapping¶
24-May-2006
- Moved to a metaclass implementation of control finding. This removes some cyclic importing that had to be worked around and other then metaclass magic makes the code a bit simpler.
- Some of the sample files would not run - so I updated them so they would (Thanks to Stefaan Himpe for pointing this out)
- Disabled saving application data (it was still being saved in Application.RecordMatch() even if the rest of the application data code is disabled. This was causing what appeared to be a memory leak where pywinauto would keep grabbing more and more memory (especially for controls that contain a lot of information). Thanks to Frank Martinez for leading me to this).
- Added ListViewWrapper.GetItemRect() to enable retrieving the rectangle for a particular item in the listview.
- Removed references to _ctrl() method within pywinauto as it was raising a DeprecationWarning internally even if the user was not using it.
0.3.4 Fixed issue with latest ctypes, speed gains, other changes¶
25-Apr-2006
- The latest version of ctypes (0.9.9.6) removed the code generator I was using some generated code in win32functions.py (stdcall). I was not using those functions so I just commented them out.
- Started the process of renaming methods of the
Application
andWindowSpecification
classes. I will be converting names toUppercaseNames_()
. The trailing_
is to disambiguate the method names from potential Window titles. - Updated how print_control_identifiers works so that it now always prints the disambiguated control name. (even for single controls)
- Added __hash__ to HwndWrapper so that controls could be dictionary keys.
- Caching various information at various points. For example I cache how well two pieces of text match. For short scripts this has little impact - but for larger script it could well have a major impact. Also caching information for controls that cannot change e.g. TopLeveParent, Parent, etc
0.3.3 Added some methods, and fixed some small bugs¶
19-Apr-2006
- Added a wait for the control to be active and configurable sleeps after ‘modifying’ actions (e.g. Select, Deselect, etc)
- Fixed Timings.Slow() and Timings.Fast() - they could in certain circumstances do the opposite! If you had already set a timing slower or faster then they would set it then they would blindly ignore that and set their own times. I added functionality that they will take either the slowest or fastest of the new/current setting rather then blindly setting to the new value.
- Fixed some hidden bugs with HwndWrapper.CloseClick()
- Fixed a bug in setup.py that would raise an error when no argument was specified
- Added an argument to HwndWrapper.SendMessageTimeout so that the wait options could be passed in.
- Added HwndWrapper.Close(), Maximize(), Minimize(), Restore() and GetShowState().
- Commented out all deprecated methods (will be removed completely in some future release).
- Added Application.kill_() method - which closes all windows and kills the application. If the application is asking if you want to save your changes - you will not be able to click yes or no and the application will be killed anyway!.
0.3.2 Fixed setup.py and some typos¶
31-Mar-2006
- Fixed the spelling of Stefaan Himpe’s name
- Fixed setup.py which was working for creating a distribution but not for installing it (again thanks to Stefaan for pointing it out!)
0.3.1 Performance tune-ups¶
30-Mar-2006
- Change calculation of distance in findbestmatch.GetNonTextControlName() so that it does not need to square or get the square root to find the real distance - as we only need to compare values - not have the actual distance. (Thanks to Stefaan Himpe)
- Compiled regular expression patterns before doing the match to avoid compiling the regular expression for window that is being tested (Thanks to Stefaan Himpe)
- Made it easier to add your own control tests by adding a file extra_tests.py which needs to export a ModifyRegisteredTests() method. Also cleaned up the code a little.
- Updated notepad_fast.py to make it easier to profile (adde a method)
- Changed WrapHandle to use a cache for classes it has matched - this is to avoid having to match against all classes constantly.
- Changed default timeout in SendMessageTimeout to .001 seconds from .4 seconds this results in a significant speedup. Will need to make this value modifiable via the timing module/routine.
- WaitNot was raising an error if the control was not found - it should have returned (i.e. success - control is not in any particular state because it does not exist!).
- Added ListViewWrapper.Deselect() per Chistophe Keller’s suggestion. While I was at it I added a check on the item value passed in and added a call to WaitGuiIdle(self) so that the control has a chance to process the message.
- Changed doc templates and moved dependencies into pywinauto subversion to ensure that all files were availabe at www.openqa.org and that they are not broken when viewed there.
- Moved all timing information into the timings.Timings class. There are some simple methods for changing the timings.
0.3.0 Added Application data - now useful for localization testing¶
20-Mar-2006
Added automatic Application data collection which can be used when running the same test on a different spoken language version. Support is still preliminary and is expected to change. Please treat as early Alpha.
If you have a different language version of Windows then you can try this out by running the notepad_fast.py example with the langauge argument e.g.
examples\notepad_fast.py language
This will load the application data from the supplied file notepad_fast.pkl and use it for finding the right menu items and controls to select.
Test implementation to make it easier to start using an application. Previously you needed to write code like
app = Application().connect_(title = 'Find') app.Find.Close.Click() app.NotePad.MenuSelect("File->Exit")
1st change was to implement static methods
start()
andconnect()
. These methods return a new Application instance so the above code becomes:app = Application.connect(title = 'Find') app.Find.Close.Click() app.NotePad.MenuSelect("File->Exit")
I also wanted to make it easier to start working with a simple application - that may or may not have only one dialog. To make this situation easier I made
window_()
not throw if the application has not beenstart()ed
orconnect()ed
first. This leads to simpler code like:app = Application() app.Find.Close.Click() app.NotePad.MenuSelect("File->Exit")
What happens here is that when you execute any of Application.window_(), Application.__getattr__() or Application.__getitem__() when the application hasn’t been connected or started. It looks for the window that best matches your specification and connects the application to that process.
This is extra functionality - existing connect_() and start_() methods still exist
Fixed HwndWrapper.SetFocus() so that it would work even if the window was not in the foreground. (it now makes the window foreground as well as giving it focus). This overcomes a restriction in Windows where you can only change the foreground window if you own the foreground window.
Changed some 2.4’isms that an anonymous commenter left on my blog :-) with these changes pywinauto should run on Python 2.3 (though I haven’t done extensive testing).
Commented out controls.common_controls.TabControlWrapper.GetTabState() and TabStates() as these did not seem to be returning valid values anyway.
Fixed documentation issues were parts of the documentation were not getting generated to the HTML files.
Fixed issue where MenuSelect would sometimes not work as expected. Some Menu actions require that the window that owns the menu be active. Added a call to SetFocus() before selecting a menu item to ensure that the window was active.
Fixed Bug 1452832 where clipboard was not closed in clipboard.GetData()
Added more unit tests now up to 248 from 207
0.2.5 More refactoring, more tests¶
07-Mar-2006
Added wrapper classes for Menus and MenuItems this enabled cleaner interaction with Menu’s. It also gives more functionality - you can now programmatically Click() on menus, and query if a menu item is checked or not.
Added application.WindowSpecification.Wait() and WaitNot() methods. These methods allow you to wait for a control to exist, be visible, be enabled, be ready (both enabled and visible!) or to wait for the control to not be in any of these states. WaitReady(), WaitNotEnabled(), WaitNotVisible() now use these methods. I was able to also add the missing methods WaitNotReady(), WaitEnabled(), WaitVisible(), WaitExists(), WaitnotExists(). Please use Wait() and WaitNot() as I have Deprecated these Wait* methods.
Slightly modified timeout waits for control resolution so that a timed function more accurately follows the timeout value specified.
Added application.Application.start() and connect() static methods. These methods are factory methods in that they will return an initialized Application instance. They work exactly the same as start_() and connect() as they are implemented in terms of those.
from pywinauto.application import Application notepad = Application.start(“notepad”) same_notepad = Application.connect(path = “notepad”)
Updated the examples to follow changes to the code - and to make them a little more robust.
Added a new Controls Overview document page which lists all the actions on all controls.
Added more unit tests now up to 207 from 134 (added 68 tests)
0.2.1 Small Release number - big changes¶
17-Feb-2006
Quick release to get many changes out there - but this release has been less tested then I would like for a .3 release.
Allow access to non text controls using the closest Text control. This closest text control will normally be the static/label associated with the control. For example in Notepad, Format->Font dialog, the 1st combobox can be refered to as “FontComboBox” rather than “ComboBox1”
Added a new control wrapper -
PopupMenuWrapper
for context menu’s You can now work easily with context menu’s e.g.app.Notepad.Edit.RightClick() # need to use MenuClick rather then MenuSelect app.PopupMenu.MenuClick("Select All") app.Notepad.Edit.RightClick() app.PopupMenu.MenuClick("Copy")
I could think of merging the
RightClick()
andMenuSelect()
into one methodContextMenuSelect()
if that makes sense to most people.Added Support for Up-Down controls
Not all top level windows now have a FriendlyClassName of “Dialog”. I changed this because it made it hard to get windows of a particular class. For example the main Notepad window has a class name of “Notepad”.
This was primarily implemented due to work I did getting the System Tray.
Renamed
StatusBarWrapper.PartWidths()
toPartRightEdges()
as this is more correct for what it returns.Changed HwndWrapper.Text() and SetText() to WindowText() and SetWindowText() respectively to try and make it clearer that it is the text returned by GetWindowText and not the text that is visible on the control. This change also suggested that EditWrapper.SetText() be changed to SetEditText() (though this is not a hard requirement EditWrapper.SetText() still exists - but may be deprecated.
Added ClickInput, DoubleClickInput, RightClickInput, PressMouseInput ReleaseMouseInput to HwndWrapper - these use SendInput rather then WM_LBUTTONDOWN, WM_RBUTTONUP, etc used by Click, DoubleClick etc.
I also added a MenuClick method that allows you to click on menu items. This means you can now ‘physically’ drop menus down.
Some further working with tooltips that need to be cleaned up.
Fixed a bug where coordinates passed to any of the Click operations had the X and Y coordinates swapped.
Added new MenuItem and Menu classes that are to the most part hidden but you can get a menu item by doing
app.Notepad.MenuItem("View") app.Notepad.MenuItem("View->Status Bar")
MenuItems have various actions so for example you can use
MenuItem.IsChecked()
to check if the menu item is checked. Among other methods there areClick()
andEnabled()
.Modified the ‘best match’ algorithm for finding controls. It now searches a couple of times, and tries to find the best fit for the text passed to it. The idea here is to make it more “Select what I want - not that other thing that looks a bit like what I want!”. It is possible this change could mean you need to use new identifiers in scripts - but in general very little modification should be necessary.
There was also a change to the algorithm that looked for the closest text control. It missed some obvious controls in the previous implementation. It also had a bug for controls above the control rather than to the left.
Added a new example scripts SaveFromInternetExplorer.py and SaveFromFirefox.py which show automating downloading of a page from either of these browsers.
Added yet more unit tests, there are now a total of 134 tests.
0.2.0 Significant refactoring¶
06-Feb-2006
Changed how windows are searched for (from application) This chage should not be a significant change for users
Started adding unit tests (and the have already uncovered bugs that been fixed). They also point to areas of missing functionality that will be addded with future updates
Changed from property access to Control attributes to function access If your code was accessing properties of controls then this might be a significant change! The main reasons for doing this were due to the inheritability of properties (or lack there-of!) and the additional scafolding that was required to define them all.
Updated the
DialogWrapper.MenuSelect()
method to notify the parent that it needs to initialize the menu’s before it retrieves the itemsAdded functionality to associate ‘non-text’ controls with the ‘text’ control closest to them. This allows controls to be referenced by:
app.dlg.<Nearby_text><Window_class>
e.g. to reference the “Footer” edit control in the Page Setup dialog you could use:
app.PageSetup.FooterEdit
Added a MoveWindow method to HwndWrapper
Did some more cleanup (fixing pylint warnings) but still not finished
Added some better support for .NET controls (not to be considered final)
0.1.3 Many changes, few visible¶
15-Jan-2006
Wrote doc strings for all modules, classes and functions
Ran pychecker and pylint and fixed some errors/warning
changed
_connect, _start, _window, _control, _write
respectively to
connect_, start_, window_, connect_, write_
If you forget to change
_window
,_connect
and_start
then you will probably get the following error.TypeError: '_DynamicAttributes' object is not callable
pywinauto is now a package name - you need to import it or its modules
Changes to the code to deal with pywinauto package name
Fixed searching for windows if a Parent is passed in
Added Index to retrieved MenuItem dictionary
Added a check to ensure that a windows Handle is a valid window
Refactored some of the methods in common_controls
Refactored how FriendlyClassName is discovered (and still not really happy!
0.1.2 Add Readme and rollup various changes¶
15-Jan-2006
- Updated Readme (original readme was incorrect)
- Added clipboard module
- Fixed DrawOutline part of tests.__init__.print_bugs
- Added a NotifyParent to HwndWrapper
- Make sure that HwndWrapper.ref is initialized to None
- Refactored some methods of ComboBox and ListBox
- Updated Combo/ListBox selection methods
- Removed hardcoded paths from test_application.py
- Added section to save the document as UTF-8 in MinimalNotepadTest
- Fixed EscapeSpecials and UnEscapeSpecials in XMLHelpers
- Made sure that overly large bitmaps do not break XML writing
0.1.0 Initial Release¶
6-Jan-2006
Source code reference¶
Basic User Input Modules¶
pywinauto.mouse¶
跨平台模块,模拟真实用户之类的鼠标事件
pywinauto.mouse.
click
(button='left', coords=(0, 0))¶Click at the specified coordinates
pywinauto.mouse.
double_click
(button='left', coords=(0, 0))¶Double click at the specified coordinates
pywinauto.mouse.
move
(coords=(0, 0))¶Move the mouse
pywinauto.mouse.
press
(button='left', coords=(0, 0))¶Press the mouse button
pywinauto.mouse.
release
(button='left', coords=(0, 0))¶Release the mouse button
pywinauto.mouse.
right_click
(coords=(0, 0))¶Right click at the specified coords
pywinauto.mouse.
scroll
(coords=(0, 0), wheel_dist=1)¶做鼠标滚轮
pywinauto.mouse.
wheel_click
(coords=(0, 0))¶鼠标中键单击指定的坐标
pywinauto.keyboard¶
键盘输入仿真模块
通过调用
SendKeys
方法自动键入活动窗口的键。 您可以使用任何Unicode字符(在Windows上)和下面列出的一些特殊键。 该模块也可在Linux上使用。Available key codes:
{SCROLLLOCK}, {VK_SPACE}, {VK_LSHIFT}, {VK_PAUSE}, {VK_MODECHANGE}, {BACK}, {VK_HOME}, {F23}, {F22}, {F21}, {F20}, {VK_HANGEUL}, {VK_KANJI}, {VK_RIGHT}, {BS}, {HOME}, {VK_F4}, {VK_ACCEPT}, {VK_F18}, {VK_SNAPSHOT}, {VK_PA1}, {VK_NONAME}, {VK_LCONTROL}, {ZOOM}, {VK_ATTN}, {VK_F10}, {VK_F22}, {VK_F23}, {VK_F20}, {VK_F21}, {VK_SCROLL}, {TAB}, {VK_F11}, {VK_END}, {LEFT}, {VK_UP}, {NUMLOCK}, {VK_APPS}, {PGUP}, {VK_F8}, {VK_CONTROL}, {VK_LEFT}, {PRTSC}, {VK_NUMPAD4}, {CAPSLOCK}, {VK_CONVERT}, {VK_PROCESSKEY}, {ENTER}, {VK_SEPARATOR}, {VK_RWIN}, {VK_LMENU}, {VK_NEXT}, {F1}, {F2}, {F3}, {F4}, {F5}, {F6}, {F7}, {F8}, {F9}, {VK_ADD}, {VK_RCONTROL}, {VK_RETURN}, {BREAK}, {VK_NUMPAD9}, {VK_NUMPAD8}, {RWIN}, {VK_KANA}, {PGDN}, {VK_NUMPAD3}, {DEL}, {VK_NUMPAD1}, {VK_NUMPAD0}, {VK_NUMPAD7}, {VK_NUMPAD6}, {VK_NUMPAD5}, {DELETE}, {VK_PRIOR}, {VK_SUBTRACT}, {HELP}, {VK_PRINT}, {VK_BACK}, {CAP}, {VK_RBUTTON}, {VK_RSHIFT}, {VK_LWIN}, {DOWN}, {VK_HELP}, {VK_NONCONVERT}, {BACKSPACE}, {VK_SELECT}, {VK_TAB}, {VK_HANJA}, {VK_NUMPAD2}, {INSERT}, {VK_F9}, {VK_DECIMAL}, {VK_FINAL}, {VK_EXSEL}, {RMENU}, {VK_F3}, {VK_F2}, {VK_F1}, {VK_F7}, {VK_F6}, {VK_F5}, {VK_CRSEL}, {VK_SHIFT}, {VK_EREOF}, {VK_CANCEL}, {VK_DELETE}, {VK_HANGUL}, {VK_MBUTTON}, {VK_NUMLOCK}, {VK_CLEAR}, {END}, {VK_MENU}, {SPACE}, {BKSP}, {VK_INSERT}, {F18}, {F19}, {ESC}, {VK_MULTIPLY}, {F12}, {F13}, {F10}, {F11}, {F16}, {F17}, {F14}, {F15}, {F24}, {RIGHT}, {VK_F24}, {VK_CAPITAL}, {VK_LBUTTON}, {VK_OEM_CLEAR}, {VK_ESCAPE}, {UP}, {VK_DIVIDE}, {INS}, {VK_JUNJA}, {VK_F19}, {VK_EXECUTE}, {VK_PLAY}, {VK_RMENU}, {VK_F13}, {VK_F12}, {LWIN}, {VK_DOWN}, {VK_F17}, {VK_F16}, {VK_F15}, {VK_F14}
Modifiers:
'+': {VK_SHIFT}
'^': {VK_CONTROL}
'%': {VK_MENU}
a.k.a. Alt keyExample how to use modifiers:
SendKeys('^a^c') # select all (Ctrl+A) and copy to clipboard (Ctrl+C) SendKeys('+{INS}') # insert from clipboard (Shift+Ins) SendKeys('%{F4}') # close an active window with Alt+F4
可以为特殊键指定重复计数。
{ENTER 2}
表示按两次Enter键。
Main User Modules¶
pywinauto.application module¶
pywinauto.findbestmatch¶
用于查找列表中字符串最接近匹配的模块
- exception
pywinauto.findbestmatch.
MatchError
(items=None, tofind='')¶A suitable match could not be found
- class
pywinauto.findbestmatch.
UniqueDict
¶处理使其键唯一的字典子类
find_best_matches
(search_text, clean=False, ignore_case=False)¶返回项目中search_text的最佳匹配项
- search_text要查找的文本
- clean是否清除字符串中的非文本字符
- ignore_case比较字符串不区分大小写
pywinauto.findbestmatch.
build_unique_dict
(controls)¶构建消除歧义的控件列表
分离出不同的功能,以便我们可以获得用于打印的控件标识符。
pywinauto.findbestmatch.
find_best_control_matches
(search_text, controls)¶返回与search_text最匹配的控件
这与find_best_match稍有不同,因为它构建了要使用每个控件的信息进行搜索的文本项列表。 因此,例如,有一个OK,按钮,然后以下全部添加到搜索列表:“OK”,“Button”,“OKButton”
但如果有一个ListView(没有可见的'text'),那么它只会添加“ListView”。
pywinauto.findbestmatch.
find_best_match
(search_text, item_texts, items, limit_ratio=0.5)¶返回与search_text最匹配的项目
- search_text要搜索的文本
- item_texts要搜索的文本列表
- items与要搜索的文本列表对应的项目列表(1到1)。
- limit_ratio文本与最佳匹配的匹配程度。 如果最佳匹配匹配低于此值,那么它不被视为匹配并且引发MatchError(默认值= .5)
pywinauto.findbestmatch.
get_control_names
(control, allcontrols, textcontrols)¶返回此控件的名称列表
pywinauto.findbestmatch.
get_non_text_control_name
(ctrl, controls, text_ctrls)¶通过查找上方和左侧最接近的文本控件返回此控件的名称
pywinauto.findbestmatch.
is_above_or_to_left
(ref_control, other_ctrl)¶如果other_ctrl在ref_control的上方或左侧,则返回true
pywinauto.findwindows¶
pywinauto.timings¶
所有pywinauto的计时设置
- 该模块有一个对象,应该用于所有时序调整
- timings.Timings
有几个预定义的设置
timings.Timings.Fast() timings.Timings.Defaults() timings.Timings.Slow()
以下是可以调整的各个时序设置:
- window_find_timeout (default 5)
- window_find_retry (default .09)
- app_start_timeout (default 10)
- app_start_retry (default .90)
- app_connect_timeout (default 5.)
- app_connect_retry (default .1)
- cpu_usage_interval (default .5)
- cpu_usage_wait_timeout (default 20)
- exists_timeout (default .5)
- exists_retry (default .3)
- after_click_wait (default .09)
- after_clickinput_wait (default .09)
- after_menu_wait (default .1)
- after_sendkeys_key_wait (default .01)
- after_button_click_wait (default 0)
- before_closeclick_wait (default .1)
- closeclick_retry (default .05)
- closeclick_dialog_close_wait (default 2)
- after_closeclick_wait (default .2)
- after_windowclose_timeout (default 2)
- after_windowclose_retry (default .5)
- after_setfocus_wait (default .06)
- setfocus_timeout (default 2)
- setfocus_retry (default .1)
- after_setcursorpos_wait (default .01)
- sendmessagetimeout_timeout (default .01)
- after_tabselect_wait (default .05)
- after_listviewselect_wait (default .01)
- after_listviewcheck_wait default(.001)
- listviewitemcontrol_timeout default(1.5)
- after_treeviewselect_wait default(.1)
- after_toobarpressbutton_wait default(.01)
- after_updownchange_wait default(.1)
- after_movewindow_wait default(0)
- after_buttoncheck_wait default(0)
- after_comboboxselect_wait default(.001)
- after_listboxselect_wait default(0)
- after_listboxfocuschange_wait default(0)
- after_editsetedittext_wait default(0)
- after_editselect_wait default(.02)
- drag_n_drop_move_mouse_wait default(.1)
- before_drag_wait default(.2)
- before_drop_wait default(.1)
- after_drag_n_drop_wait default(.1)
- scroll_step_wait default(.1)
- class
pywinauto.timings.
TimeConfig
¶Central storage and manipulation of timing values
Defaults
()¶将所有计时设置为默认时间
Fast
()¶设置快速计时值
目前,这会通过以下方式更改时间:超时= 1秒等待= 0秒重试= .001秒(最小!)
(如果现有时间更快,那么保持现有时间)
Slow
()¶Set slow timing values
Currently this changes the timing in the following ways: timeouts = default timeouts * 10 waits = default waits * 3 retries = default retries * 3
(if existing times are slower then keep existing times)
- exception
pywinauto.timings.
TimeoutError
¶
pywinauto.timings.
always_wait_until
(timeout, retry_interval, value=True, op=<built-in function eq>)¶每次为装饰函数/方法调用wait_until(...)的Decorator
pywinauto.timings.
always_wait_until_passes
(timeout, retry_interval, exceptions=<class 'Exception'>)¶装饰器每次为装饰的函数/方法调用wait_until_passes(...)
pywinauto.timings.
timestamp
()¶获得精确的时间戳
pywinauto.timings.
wait_until
(timeout, retry_interval, func, value=True, op=<built-in function eq>, *args, **kwargs)¶等到
op(function(* args, ** kwargs), value)
为True或直到超时到期
- timeout该功能将尝试该功能多长时间
- retry_interval重试之间等待的时间
- func将要执行的功能
- value要比较的值(默认为True)
- op比较函数(默认为相等)
- args调用时传递给func的可选参数
- kwargs调用时要传递给func的可选关键字参数
返回函数的返回值如果操作超时,则函数的返回值位于引发的异常的“function_value”属性中。
e.g.
try: # wait a maximum of 10.5 seconds for the # the objects item_count() method to return 10 # in increments of .5 of a second wait_until(10.5, .5, self.item_count, 10) except TimeoutError as e: print("timed out")
pywinauto.timings.
wait_until_passes
(timeout, retry_interval, func, exceptions=<class 'Exception'>, *args, **kwargs)¶Wait until
func(*args, **kwargs)
does not raise one of the exceptions
- timeout该功能将尝试该功能多长时间
- retry_interval重试之间等待的时间
- func将要执行的功能
- exceptions要测试的异常列表(默认值:Exception)
- args调用时传递给func的可选参数
- kwargs调用时要传递给func的可选关键字参数
返回函数的返回值如果操作超时,则引发的原始异常位于引发的异常的“original_exception”属性中。
e.g.
try: # wait a maximum of 10.5 seconds for the # window to be found in increments of .5 of a second. # P.int a message and re-raise the original exception if never found. wait_until_passes(10.5, .5, self.Exists, (ElementNotFoundError)) except TimeoutError as e: print("timed out") raise e.
控件参考¶
pywinauto.base_wrapper¶
所有后端中所有包装器的基类
- class
pywinauto.base_wrapper.
BaseMeta
¶Wrapper对象的抽象元类
- static
find_wrapper
(element)¶Abstract static method to find an appropriate wrapper
- class
pywinauto.base_wrapper.
BaseWrapper
(element_info, active_backend)¶元素的抽象包装。
All other wrappers are derived from this.
can_be_label
= False¶
capture_as_image
(rect=None)¶Return a PIL image of the control.
See PIL documentation to know what you can do with the resulting image.
children
(**kwargs)¶将此元素的子元素作为列表返回
它返回BaseWrapper(或子类)实例的列表。 如果没有子项,则返回空列表。
class_name
()¶返回elenemt的类名
click_input
(button='left', coords=(None, None), button_down=True, button_up=True, double=False, wheel_dist=0, use_log=True, pressed='', absolute=False, key_down=True, key_up=True)¶单击指定的坐标
- button The mouse button to click. One of ‘left’, ‘right’, ‘middle’ or ‘x’ (Default: ‘left’, ‘move’ is a special case)
- coords点击的坐标。(默认值:控件的中心)
- double是否执行双击(默认值:False)
- wheel_dist移动鼠标滚轮的距离(默认值:0)
- NOTES:
这与click方法的不同之处在于它需要控件在屏幕上可见,但执行更逼真的“点击”模拟。
如果用户移动鼠标,此方法也很容易受到影响,因为在click_input完成之前可以轻松地将鼠标从控件上移开。
client_to_screen
(client_point)¶Maps point from client to screen coordinates
control_count
()¶返回此控件的子项数
control_id
()¶返回元素的ID
只有控件具有有效的ID - 对话框通常没有分配ID。
ID通常在窗口中标识控件 - 但是可能存在重复的ID,例如对话框中的标签可能具有重复的ID。
descendants
(**kwargs)¶以列表的形式返回此元素的后代
它返回BaseWrapper(或子类)实例的列表。 如果没有后代,则返回空列表。
double_click_input
(button='left', coords=(None, None))¶双击指定的坐标
drag_mouse_input
(dst=(0, 0), src=None, button='left', pressed='', absolute=True)¶单击src,将其拖放到dst
- dst是目标包装器对象或仅是坐标。
- src是源包装器对象或坐标。 如果src为None,则self用作源对象。
- 按钮是拖动过程中要按住的鼠标按钮。 它可以是“left”,“right”,“middle”或“x”
- pressed是键盘在拖动过程中按下的键。
- absolute指定是否对鼠标指针位置使用绝对坐标
draw_outline
(colour='green', thickness=2, fill=<MagicMock name='mock.win32defines.BS_NULL' id='140016409767608'>, rect=None)¶在窗口周围画一个轮廓。
- colour可以是整数,也可以是“red”,“green”,“blue”(默认为“绿色”)
- thickness矩形的线宽(默认为2)
- fill如何填充矩形(默认BS_NULL)
- rect要绘制的矩形的坐标(默认为控件的矩形)
element_info
¶获取ElementInfo对象的只读属性
friendly_class_name
()¶返回控件的友好类名
在某些情况下,这与控制类不同。 class_name()是控件的实际“Registered”元素类,而friendly_class_name()希望对用户更有意义。
例如,Checkbox实现为按钮 - 因此CheckBox的类是“Button” - 但友好类是“CheckBox”
friendlyclassname
= None¶
get_properties
()¶将控件的属性作为字典返回。
has_title
= True¶
is_child
(parent)¶如果此元素是'parent'的子元素,则返回True。
当元素是另一个元素的直接元素时,元素是另一个元素的子元素。 如果父元素是子元素的父元素链,则元素是给定元素的直接后代。
is_dialog
()¶如果控件是顶级窗口,则返回true
is_enabled
()¶元素是否启用
检查是否同时启用了拥有此元素的顶级父级(可能是对话框)和元素本身。
如果要等待某个元素被启用(或等待它被禁用),请使用
Application.wait('visible')
或Application.wait_not('visible')
。如果要在未启用元素的情况下立即引发异常,则可以使用BaseWrapper.verify_enabled()。 如果窗口既不可见又启用,则会引发BaseWrapper.VerifyReady()。
is_visible
()¶元素是否可见
Checks that both the top level parent (probably dialog) that owns this element and the element itself are both visible.
If you want to wait for an element to become visible (or wait for it to become hidden) use
Application.wait('visible')
orApplication.wait_not('visible')
.If you want to raise an exception immediately if an element is not visible then you can use the BaseWrapper.verify_visible(). BaseWrapper.verify_actionable() raises if the element is not both visible and enabled.
iter_children
(**kwargs)¶迭代这个元素的子元素
它返回BaseWrapper(或子类)实例的生成器。
iter_descendants
(**kwargs)¶迭代这个元素的子类
它返回BaseWrapper(或子类)实例的生成器。
move_mouse_input
(coords=(0, 0), pressed='', absolute=True)¶移动鼠标
parent
()¶返回此元素的父元素
请注意,控件的父级不一定是对话框或其他主窗口。 例如,组框可以是某些单选按钮的父级。
要获取主(或顶级)窗口,请使用BaseWrapper.top_level_parent()。
press_mouse_input
(button='left', coords=(None, None), pressed='', absolute=True, key_down=True, key_up=True)¶使用SendInput按下鼠标按钮
process_id
()¶返回拥有此窗口的进程的ID
rectangle
()¶返回元素的矩形
矩形()是屏幕上元素的矩形。 坐标从屏幕的左上角给出。
此方法返回RECT结构,该结构具有top,left,right,bottom属性。 并且有方法width()和height()。 有关更多信息,请参阅win32structures.RECT。
release_mouse_input
(button='left', coords=(None, None), pressed='', absolute=True, key_down=True, key_up=True)¶Release the mouse button
right_click_input
(coords=(None, None))¶Right click at the specified coords
root
()¶返回根元素包装器(桌面)
set_focus
()¶将焦点设置为此元素
texts
()¶返回此控件的每个项目的文本
它是控件的字符串列表。 经常重写它以从具有多个项的控件中提取所有字符串。
它始终是包含一个或多个字符串的列表:
- 第一个元素是控件的窗口文本
- 后续元素包含控件的任何项目的文本(例如,列表框/组合框中的项目,tabcontrol中的选项卡)
top_level_parent
()¶返回此控件的顶级窗口
TopLevel父级与父级不同,父级是拥有此元素的元素 - 但它可能不是对话框/主窗口。 例如,大多数组合框都有编辑。 ComboBox是Edit控件的父级。
这将始终返回一个有效的窗口元素(如果控件没有顶级父级,则返回控件本身 - 因为它已经是顶级窗口!)
type_keys
(keys, pause=None, with_spaces=False, with_tabs=False, with_newlines=False, turn_off_numlock=True, set_foreground=True)¶使用keyboard.SendKeys键入元素的键
这使用重写的keyboard python模块,您可以在其中找到有关keys的用途的文档。
verify_actionable
()¶验证该元素是否可见并已启用
如果未分别启用或可见,则提升ElementNotEnalbed或ElementNotVisible。
verify_enabled
()¶验证元素是否已启用
首先检查元素的父元素是否已启用(如果没有父元素则跳过),然后检查元素本身是否已启用。
verify_visible
()¶Verify that the element is visible
Check first if the element’s parent is visible. (skip if no parent), then check if element itself is visible.
wait_for_idle
()¶后端特定函数等待线程或窗口的空闲状态
was_maximized
()¶在最小化之前指示窗口是否最大化
wheel_mouse_input
(coords=(None, None), wheel_dist=1, pressed='')¶Do mouse wheel
window_text
()¶窗口文本的元素
相当多的控件具有其他可见的文本,例如,编辑控件通常具有window_text的空字符串,但仍然在编辑窗口中显示文本。
windowclasses
= []¶
writable_props
¶构建要写入的默认属性的列表。
派生类可以覆盖或扩展此列表,具体取决于它们需要多少控制。
- exception
pywinauto.base_wrapper.
ElementNotEnabled
¶未启用元素时引发
- exception
pywinauto.base_wrapper.
ElementNotVisible
¶元素不可见时引发
- exception
pywinauto.base_wrapper.
InvalidElement
¶传递无效元素时引发
pywinauto.base_wrapper.
remove_non_alphanumeric_symbols
(s)¶使文本可用于属性名称
pywinauto.controls.hwndwrapper¶
pywinauto.controls.common_controls¶
pywinauto.controls.win32_controls¶
pywinauto.controls.uiawrapper¶
UI自动化元素的基本包装
- class
pywinauto.controls.uiawrapper.
LazyProperty
(fget)¶Bases:
object
A lazy evaluation of an object attribute.
The property should represent immutable data, as it replaces itself. Provided by: http://stackoverflow.com/a/6849299/1260742
- class
pywinauto.controls.uiawrapper.
UIAWrapper
(element_info)¶Bases:
pywinauto.base_wrapper.BaseWrapper
Default wrapper for User Interface Automation (UIA) controls.
All other UIA wrappers are derived from this.
This class wraps a lot of functionality of underlying UIA features for working with windows.
Most of the methods apply to every single element type. For example you can click() on any element.
automation_id
()¶Return the Automation ID of the control
can_select_multiple
()¶An interface to CanSelectMultiple of the SelectionProvider pattern
Indicates whether the UI Automation provider allows more than one child element to be selected concurrently.
children_texts
()¶Get texts of the control’s children
close
()¶Close the window
Only a control supporting Window pattern should answer. If it doesn’t (menu shadows, tooltips,...), try to send “Esc” key
collapse
()¶Displays all child nodes, controls, or content of the control
An interface to Collapse method of the ExpandCollapse control pattern.
expand
()¶Displays all child nodes, controls, or content of the control
An interface to Expand method of the ExpandCollapse control pattern.
friendly_class_name
()¶Return the friendly class name for the control
This differs from the class of the control in some cases. class_name() is the actual ‘Registered’ window class of the control while friendly_class_name() is hopefully something that will make more sense to the user.
For example Checkboxes are implemented as Buttons - so the class of a CheckBox is “Button” - but the friendly class is “CheckBox”
get_expand_state
()¶Indicates the state of the control: expanded or collapsed.
An interface to CurrentExpandCollapseState property of the ExpandCollapse control pattern. Values for enumeration as defined in uia_defines module: expand_state_collapsed = 0 expand_state_expanded = 1 expand_state_partially = 2 expand_state_leaf_node = 3
get_selection
()¶An interface to GetSelection of the SelectionProvider pattern
Retrieves a UI Automation provider for each child element that is selected. Builds a list of UIAElementInfo elements from all retrieved providers.
get_show_state
()¶Get the show state and Maximized/minimzed/restored state
Returns values as following
window_visual_state_normal = 0 window_visual_state_maximized = 1 window_visual_state_minimized = 2
has_keyboard_focus
()¶Return True if the element is focused with keyboard
iface_expand_collapse
= None¶
iface_grid
= None¶
iface_grid_item
= None¶
iface_invoke
= None¶
iface_item_container
= None¶
iface_range_value
= None¶
iface_scroll
= None¶
iface_scroll_item
= None¶
iface_selection
= None¶
iface_selection_item
= None¶
iface_table
= None¶
iface_table_item
= None¶
iface_text
= None¶
iface_toggle
= None¶
iface_transform
= None¶
iface_transformV2
= None¶
iface_value
= None¶
iface_virtualized_item
= None¶
iface_window
= None¶
invoke
()¶An interface to the Invoke method of the Invoke control pattern
is_active
()¶Whether the window is active or not
is_collapsed
()¶Test if the control is collapsed
is_dialog
()¶Return true if the control is a dialog window (WindowPattern interface is available)
is_expanded
()¶Test if the control is expanded
is_keyboard_focusable
()¶Return True if the element can be focused with keyboard
is_maximized
()¶Indicate whether the window is maximized or not
is_minimized
()¶Indicate whether the window is minimized or not
is_normal
()¶Indicate whether the window is normal (i.e. not minimized and not maximized)
is_selected
()¶Indicate that the item is selected or not.
Only items supporting SelectionItem pattern should answer. Raise NoPatternInterfaceError if the pattern is not supported
Usually applied for controls like: a radio button, a tree view item, a list item.
is_selection_required
()¶An interface to IsSelectionRequired property of the SelectionProvider pattern.
This property can be dynamic. For example, the initial state of a control might not have any items selected by default, meaning that IsSelectionRequired is FALSE. However, after an item is selected the control must always have at least one item selected.
legacy_properties
()¶Get the element’s LegacyIAccessible control pattern interface properties
maximize
()¶Maximize the window
Only controls supporting Window pattern should answer
Select a menu item specified in the path
The full path syntax is specified in:
pywinauto.menuwrapper.Menu.get_menu_path()
There are usually at least two menu bars: “System” and “Application” System menu bar is a standard window menu with items like: ‘Restore’, ‘Move’, ‘Size’, ‘Minimize’, e.t.c. This menu bar usually has a “Title Bar” control as a parent. Application menu bar is often what we look for. In most cases, its parent is the dialog itself so it should be found among the direct children of the dialog. Notice that we don’t use “Application” string as a title criteria because it couldn’t work on applications with a non-english localization. If there is no menu bar has been found we fall back to look up for Menu control. We try to find the control through all descendants of the dialog
minimize
()¶Minimize the window
Only controls supporting Window pattern should answer
restore
()¶Restore the window to normal size
Only controls supporting Window pattern should answer
scroll
(direction, amount, count=1, retry_interval=0.1)¶Ask the control to scroll itself
direction can be any of “up”, “down”, “left”, “right” amount can be only “line” or “page” count (optional) the number of times to scroll retry_interval (optional) interval between scroll actions
select
()¶Select the item
Only items supporting SelectionItem pattern should answer. Raise NoPatternInterfaceError if the pattern is not supported
Usually applied for controls like: a radio button, a tree view item or a list item.
selected_item_index
()¶Return the index of a selected item
set_focus
()¶Set the focus to this element
writable_props
¶Extend default properties list.
- class
pywinauto.controls.uiawrapper.
UiaMeta
(name, bases, attrs)¶Bases:
pywinauto.base_wrapper.BaseMeta
Metaclass for UiaWrapper objects
- static
find_wrapper
(element)¶Find the correct wrapper for this UIA element
pywinauto.controls.uiawrapper.
lazy_property
¶alias of
LazyProperty
pywinauto.controls.uia_controls¶
Wrap various UIA windows controls
- class
pywinauto.controls.uia_controls.
ButtonWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap a UIA-compatible Button, CheckBox or RadioButton control
click
()¶Click the Button control by using Invoke pattern
get_toggle_state
()¶Get a toggle state of a check box control.
The toggle state is represented by an integer 0 - unchecked 1 - checked 2 - indeterminate
The following constants are defined in the uia_defines module toggle_state_off = 0 toggle_state_on = 1 toggle_state_inderteminate = 2
is_dialog
()¶Buttons are never dialogs so return False
toggle
()¶An interface to Toggle method of the Toggle control pattern.
Control supporting the Toggle pattern cycles through its toggle states in the following order: ToggleState_On, ToggleState_Off and, if supported, ToggleState_Indeterminate
Usually applied for the check box control.
The radio button control does not implement IToggleProvider, because it is not capable of cycling through its valid states. Toggle a state of a check box control. (Use ‘select’ method instead) Notice, a radio button control isn’t supported by UIA. https://msdn.microsoft.com/en-us/library/windows/desktop/ee671290(v=vs.85).aspx
- class
pywinauto.controls.uia_controls.
ComboBoxWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap a UIA CoboBox control
item_count
()¶Return the number of items in the combobox
The interface is kept mostly for a backward compatibility with the native ComboBox interface
select
(item)¶Select the ComboBox item
The item can be either a 0 based index of the item to select or it can be the string that you want to select
selected_index
()¶Return the selected index
selected_text
()¶Return the selected text or None
Notice, that in case of multi-select it will be only the text from a first selected item
texts
()¶Return the text of the items in the combobox
- class
pywinauto.controls.uia_controls.
EditWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible Edit control
get_line
(line_index)¶Return the line specified
get_value
()¶Return the current value of the element
has_title
= False¶
line_count
()¶Return how many lines there are in the Edit
line_length
(line_index)¶Return how many characters there are in the line
select
(start=0, end=None)¶Set the edit selection of the edit control
selection_indices
()¶The start and end indices of the current selection
set_edit_text
(text, pos_start=None, pos_end=None)¶Set the text of the edit control
set_text
(text, pos_start=None, pos_end=None)¶Set the text of the edit control
set_window_text
(text, append=False)¶Override set_window_text for edit controls because it should not be used for Edit controls.
Edit Controls should either use set_edit_text() or type_keys() to modify the contents of the edit control.
text_block
()¶Get the text of the edit control
texts
()¶Get the text of the edit control
writable_props
¶Extend default properties list.
- class
pywinauto.controls.uia_controls.
HeaderItemWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible Header Item control
- class
pywinauto.controls.uia_controls.
HeaderWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible Header control
- class
pywinauto.controls.uia_controls.
ListItemWrapper
(elem, container=None)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible ListViewItem control
is_checked
()¶Return True if the ListItem is checked
Only items supporting Toggle pattern should answer. Raise NoPatternInterfaceError if the pattern is not supported
texts
()¶Return a list of item texts
- class
pywinauto.controls.uia_controls.
ListViewWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible ListView control
cell
(row, column)¶Return a cell in the ListView control
Only for controls with Grid pattern support
- row is an index of a row in the list.
- column is an index of a column in the specified row.
The returned cell can be of different control types. Mostly: TextBlock, ImageControl, EditControl, DataItem or even another layer of data items (Group, DataGrid)
column_count
()¶Return the number of columns
columns
()¶Get the information on the columns of the ListView
get_column
(col_index)¶Get the information for a column of the ListView
get_header_control
()¶Return Header control associated with the ListView
get_item
(row)¶Return an item of the ListView control
- row can be either an index of the row or a string with the text of a cell in the row you want returned.
get_item_rect
(item_index)¶Return the bounding rectangle of the list view item
The method is kept mostly for a backward compatibility with the native ListViewWrapper interface
get_items
()¶Return all items of the ListView control
get_selected_count
()¶Return a number of selected items
The call can be quite expensieve as we retrieve all the selected items in order to count them
item
(row)¶Return an item of the ListView control
- row can be either an index of the row or a string with the text of a cell in the row you want returned.
item_count
()¶A number of items in the ListView
items
()¶Return all items of the ListView control
texts
()¶Return a list of item texts
writable_props
¶Extend default properties list.
- class
pywinauto.controls.uia_controls.
MenuItemWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible MenuItem control
items
()¶Find all items of the menu item
select
()¶Apply Select pattern
- class
pywinauto.controls.uia_controls.
MenuWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible MenuBar or Menu control
item_by_index
(idx)¶Find a menu item specified by the index
item_by_path
(path, exact=False)¶Find a menu item specified by the path
The full path syntax is specified in:
controls.menuwrapper.Menu.get_menu_path()
Note: $ - specifier is not supported
items
()¶Find all menu items
- class
pywinauto.controls.uia_controls.
SliderWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible Slider control
has_title
= False¶
large_change
()¶Get a large change of slider’s thumb
This change is achieved by pressing PgUp and PgDown keys when slider’s thumb has keyboard focus.
max_value
()¶Get the maximum value of the Slider
min_value
()¶Get the minimum value of the Slider
set_value
(value)¶Set position of slider’s thumb
small_change
()¶Get a small change of slider’s thumb
This change is achieved by pressing left and right arrows when slider’s thumb has keyboard focus.
value
()¶Get a current position of slider’s thumb
- class
pywinauto.controls.uia_controls.
TabControlWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible Tab control
get_selected_tab
()¶Return an index of a selected tab
select
(item)¶Select a tab by index or by name
tab_count
()¶Return a number of tabs
texts
()¶Tabs texts
- class
pywinauto.controls.uia_controls.
ToolbarWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible ToolBar control
The control’s children usually are: Buttons, SplitButton, MenuItems, ThumbControls, TextControls, Separators, CheckBoxes. Notice that ToolTip controls are children of the top window and not of the toolbar.
Return a button by the specified identifier
- button_identifier can be either an index of a button or a string with the text of the button.
- exact flag specifies if the exact match for the text look up has to be applied.
Return a number of buttons on the ToolBar
Find where the button is and toggle it
- button_identifier can be either an index of the button or a string with the text on the button.
- make_checked specifies the required toggled state of the button. If the button is already in the specified state the state isn’t changed.
- exact flag specifies if the exact match for the text look up has to be applied
texts
()¶Return texts of the Toolbar
writable_props
¶Extend default properties list.
- class
pywinauto.controls.uia_controls.
TooltipWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible Tooltip control
- class
pywinauto.controls.uia_controls.
TreeItemWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible TreeItem control
In addition to the provided methods of the wrapper additional inherited methods can be especially helpful: select(), extend(), collapse(), is_extended(), is_collapsed(), click_input(), rectangle() and many others
ensure_visible
()¶Make sure that the TreeView item is visible
get_child
(child_spec, exact=False)¶Return the child item of this item
Accepts either a string or an index. If a string is passed then it returns the child item with the best match for the string.
is_checked
()¶Return True if the TreeItem is checked
Only items supporting Toggle pattern should answer. Raise NoPatternInterfaceError if the pattern is not supported
sub_elements
()¶Return a list of all visible sub-items of this control
- class
pywinauto.controls.uia_controls.
TreeViewWrapper
(elem)¶Bases:
pywinauto.controls.uiawrapper.UIAWrapper
Wrap an UIA-compatible Tree control
get_item
(path, exact=False)¶Read a TreeView item
- path a path to the item to return. This can be one of the following:
- A string separated by \ characters. The first character must be \. This string is split on the \ characters and each of these is used to find the specific child at each level. The \ represents the root item - so you don’t need to specify the root itself.
- A list/tuple of strings - The first item should be the root element.
- A list/tuple of integers - The first item the index which root to select. Indexing always starts from zero: get_item((0, 2, 3))
- exact a flag to request exact match of strings in the path or apply a fuzzy logic of best_match thus allowing non-exact path specifiers
item_count
()¶Return a number of items in TreeView
print_items
()¶Print all items with line indents
roots
()¶Return root elements of TreeView
writable_props
¶Extend default properties list.
预先提供的测试¶
pywinauto.tests.allcontrols¶
获取所有控件测试
What is checked此测试不进行实际测试,只返回每个控件。
How is it checked在对话框中的所有控件上进行循环,并将每个控件添加到错误列表中
When is a bug reported For each control.
Bug Extra Information There is no extra information associated with this bug type
Is Reference dialog needed No,but if available the reference control will be returned with the localised control.
False positive bug reports Not possible
Test Identifier The identifier for this test/bug is “AllControls”
pywinauto.tests.allcontrols.
AllControlsTest
(windows)¶Returns just one bug for each control
pywinauto.tests.asianhotkey¶
Asian Hotkey Format Test
What is checked
This test checks whether the format for shortcuts/hotkeys follows the standards for localised Windows applications. This format is {localised text}({uppercase hotkey}) so for example if the English control is “&Help” the localised control for Asian languages should be “LocHelp(H)”
How is it checked
After checking whether this control displays hotkeys it examines the 1st string of the control to make sure that the format is correct. If the reference control is available then it also makes sure that the hotkey character is the same as the reference. Controls with a title of less than 4 characters are ignored. This has been done to avoid false positive bug reports for strings like “&X:”.
When is a bug reported
A bug is reported when a control has a hotkey and it is not in the correct format. Also if the reference control is available a bug will be reported if the hotkey character is not the same as used in the reference
Bug Extra Information
This test produces 2 different types of bug: BugType: “AsianHotkeyFormat” There is no extra information associated with this bug type
BugType: “AsianHotkeyDiffRef”
There is no extra information associated with this bug type
Is Reference dialog needed
The reference dialog is not needed. If it is unavailable then only bugs of type “AsianHotkeyFormat” will be reported, bug of type “AsianHotkeyDiffRef” will not be found.
False positive bug reports
There should be very few false positive bug reports when testing Asian software. If a string is very short (eg “&Y:”) but is padded with spaces then it will get reported.
Test Identifier
The identifier for this test/bug is “AsianHotkeyTests”
pywinauto.tests.asianhotkey.
AsianHotkeyTest
(windows)¶Return the repeated hotkey errors
pywinauto.tests.comboboxdroppedheight¶
ComboBox dropped height Test
What is checked It is ensured that the height of the list displayed when the combobox is dropped down is not less than the height of the reference.
How is it checked The value for the dropped rectangle can be retrieved from windows. The height of this rectangle is calculated and compared against the reference height.
When is a bug reported If the height of the dropped rectangle for the combobox being checked is less than the height of the reference one then a bug is reported.
Bug Extra Information There is no extra information associated with this bug type
Is Reference dialog needed The reference dialog is necessary for this test.
False positive bug reports No false bugs should be reported. If the font of the localised control has a smaller height than the reference then it is possible that the dropped rectangle could be of a different size.
Test Identifier The identifier for this test/bug is “ComboBoxDroppedHeight”
pywinauto.tests.comboboxdroppedheight.
ComboBoxDroppedHeightTest
(windows)¶Check if each combobox height is the same as the reference
pywinauto.tests.comparetoreffont¶
Compare against reference font test
What is checked This test checks all the parameters of the font for the control against the font for the reference control. If any value is different then this is reported as a bug. Here is a list of all the possible values that are tested: lfFaceName The name of the font lfHeight The height of the font lfWidth Average width of characters lfEscapement Angle of text lfOrientation Another angle for the text! lfWeight How bold the text is lfItalic If the font is italic lfUnderline If the font is underlined lfStrikeOut If the font is struck out lfCharSet The character set of the font lfOutPrecision The output precision lfClipPrecision The clipping precision lfQuality The output quality lfPitchAndFamily The pitch and family
How is it checked Each property of the font for the control being tested is compared against the equivalent property of the reference control font for equality.
When is a bug reported For each property of the font that is not identical to the reference font a bug is reported. So for example if the Font Face has changed and the text is bold then (at least) 2 bugs will be reported.
Bug Extra Information The bug contains the following extra information Name Description ValueType What value is incorrect (see above), String Ref The reference value converted to a string, String Loc The localised value converted to a string, String
Is Reference dialog needed This test will not run if the reference controls are not available.
False positive bug reports Running this test for Asian languages will result in LOTS and LOTS of false positives, because the font HAS to change for the localised text to display properly.
Test Identifier The identifier for this test/bug is “CompareToRefFont”
pywinauto.tests.comparetoreffont.
CompareToRefFontTest
(windows)¶Compare the font to the font of the reference control
pywinauto.tests.leadtrailspaces¶
Different Leading and Trailing Spaces Test
What is checked Checks that the same space characters (<space>, <tab>, <enter>, <vertical tab>) are before and after all non space characters in the title of the control when compared to the reference control.
How is it checked Find the 1st non-space character, and the characters of the title up to that are the leading spaces. Find the last non-space character, and the characters of the title after that are the trailing spaces. These are then compared to the lead and trail spaces from the reference control and if they are not exactly the then a bug is reported.
When is a bug reported When either the leading or trailing spaces of the control being tested does not match the equivalent spaces of the reference control exactly.
Bug Extra Information The bug contains the following extra information
Lead-Trail Whether this bug report is for the leading or trailing spaces of the control, String
This will be either:
- “Leading” bug relating to leading spaces
- “Trailing” bug relating to trailing spaces
Ref The leading or trailings spaces of the reference string (depending on Lead-Trail value), String
Loc The leading or trailings spaces of the local string (depending on Lead-Trail value), String
Is Reference dialog needed This test will not run if the reference controls are not available.
False positive bug reports This is usually not a very important test, so if it generates many false positives then we should consider removing it.
Test Identifier The identifier for this test/bug is “LeadTrailSpaces”
pywinauto.tests.leadtrailspaces.
GetLeadSpaces
(title)¶Return the leading spaces of the string
pywinauto.tests.leadtrailspaces.
GetTrailSpaces
(title)¶Return the trailing spaces of the string
pywinauto.tests.leadtrailspaces.
LeadTrailSpacesTest
(windows)¶Return the leading/trailing space bugs for the windows
pywinauto.tests.miscvalues¶
Miscellaneous Control properties Test
What is checked This checks various values related to a control in windows. The values tested are class_name The class type of the control style The Style of the control (GetWindowLong) exstyle The Extended Style of the control (GetWindowLong) help_id The Help ID of the control (GetWindowLong) control_id The Control ID of the control (GetWindowLong) user_data The User Data of the control (GetWindowLong) Visibility Whether the control is visible or not
How is it checked After retrieving the information for the control we compare it to the same information from the reference control.
When is a bug reported If the information does not match then a bug is reported.
Bug Extra Information The bug contains the following extra information Name Description ValueType What value is incorrect (see above), String Ref The reference value converted to a string, String Loc The localised value converted to a string, String
Is Reference dialog needed This test will not run if the reference controls are not available.
False positive bug reports Some values can change easily without any bug being caused, for example User Data is actually meant for programmers to store information for the control and this can change every time the software is run.
Test Identifier The identifier for this test/bug is “MiscValues”
pywinauto.tests.miscvalues.
MiscValuesTest
(windows)¶Return the bugs from checking miscelaneous values of a control
pywinauto.tests.missalignment¶
Missalignment Test
What is checked This test checks that if a set of controls were aligned on a particular axis in the reference dialog that they are all aligned on the same axis.
How is it checked A list of all the reference controls that are aligned is created (ie more than one control with the same Top, Left, Bottom or Right coordinates). These controls are then analysed in the localised dialog to make sure that they are all aligned on the same axis.
When is a bug reported A bug is reported when any of the controls that were aligned in the reference dialog are no longer aligned in the localised control.
Bug Extra Information The bug contains the following extra information Name Description AlignmentType This is either LEFT, TOP, RIGHT or BOTTOM. It tells you how the controls were aligned in the reference dialog. String AlignmentRect Gives the smallest rectangle that surrounds ALL the controls concerned in the bug, rectangle
Is Reference dialog needed This test cannot be performed without the reference control. It is required to see which controls should be aligned.
False positive bug reports It is quite possible that this test reports false positives: 1. Where the controls only just happen to be aligned in the reference dialog (by coincidence) 2. Where the control does not have a clear boundary (for example static labels or checkboxes) they may be miss-aligned but it is not noticeable that they are not.
Test Identifier The identifier for this test/bug is “Missalignment”
pywinauto.tests.missalignment.
MissalignmentTest
(windows)¶Run the test on the windows passed in
pywinauto.tests.missingextrastring¶
Different number of special character sequences Test
What is checked This test checks to make sure that certain special character sequences appear the in the localised if they appear in the reference title strings. These strings usually mean something to the user but the software internally does not care if they exist or not. The list that is currently checked is: “>>”, “>”, “<<”, “<”, ”:”(colon), ”...”, “&&”, “&”, “”
How is it checked For each of the string to check for we make sure that if it appears in the reference that it also appears in the localised title.
- When is a bug reported
- If the reference has one of the text strings but the localised does not a bug is reported.
- If the localised has one of the text strings but the reference does not a bug is reported.
Bug Extra Information The bug contains the following extra information
MissingOrExtra Whether the characters are missing or extra from the controls being check as compared to the reference, (String with following possible values)
- “MissingCharacters” The characters are in the reference but not in the localised.
- “ExtraCharacters” The characters are not in the reference but are in the localised.
MissingOrExtraText What character string is missing or added, String
Is Reference dialog needed This test will not run if the reference controls are not available.
False positive bug reports Currently this test is at a beta stage filtering of the results is probably necessary at the moment.
Test Identifier The identifier for this test/bug is “MissingExtraString”
pywinauto.tests.missingextrastring.
MissingExtraStringTest
(windows)¶Return the errors from running the test
pywinauto.tests.overlapping¶
Overlapping Test
What is checked The overlapping test checks for controls that occupy the same space as some other control in the dialog.
- If the reference controls are available check for each pair of controls:
- If controls are exactly the same size and position in reference then make sure that they are also in the localised.
- If a reference control is wholly contained in another make sure that the same happens for the controls being tested.
- If the reference controls are not available only the following check can be done
- If controls are overlapped in localised report a bug (if reference is available it is used just to say if this overlapping happens in reference also)
How is it checked Various tests are performed on each pair of controls to see if any of the above conditions are met. The most specific tests that can be performed are done 1st so that the bugs reported are as specific as possible. I.e. we report that 2 controls are not exactly overlapped when they should be rather than jut reporting that they are overlapped which contains less information.
When is a bug reported A bug is reported when:
- controls are overlapped (but not contained wholly, and not exactly overlapped)
- reference controls are exactly overlapped but they are not in tested dialog
- one reference control is wholly contained in another but not in tested dialog
Bug Extra Information This test produces 3 different types of bug: BugType: “Overlapping” Name Description OverlappedRect <What this info is>, rectangle
BugType - “NotContainedOverlap” There is no extra information associated with this bug type
BugType - “NotExactOverlap” There is no extra information associated with this bug type
Is Reference dialog needed For checking whether controls should be exactly overlapped and whether they should be wholly contained the reference controls are necessary. If the reference controls are not available then only simple overlapping of controls will be checked.
False positive bug reports If there are controls in the dialog that are not visible or are moved dynamically it may cause bugs to be reported that do not need to be logged. If necessary filter out bugs with hidden controls.
Test Identifier The identifier for this test is “Overlapping”
- class
pywinauto.tests.overlapping.
OptRect
¶
pywinauto.tests.overlapping.
OverlappingTest
(windows)¶Return the repeated hotkey errors
pywinauto.tests.repeatedhotkey¶
Repeated Hotkeys Test
What is checked This test checks all the controls in a dialog to see if there are controls that use the same hotkey character.
How is it checked A list of all the hotkeys (converted to uppercase) used in the dialog is created. Then this list is examined to see if any hotkeys are used more than once. If any are used more than once a list of all the controls that use this hotkey are compiled to be used in the bug report.
When is a bug reported If more than one control has the same hotkey then a bug is reported.
Bug Extra Information The bug contains the following extra information Name Description RepeatedHotkey This is the hotkey that is repeated between the 2 controls converted to uppercase, String CharsUsedInDialog This is a list of all the hotkeys used in the dialog, String AllCharsInDialog This is a list of all the characters in the dialog for controls that have a hotkeys, String AvailableInControlS A list of the available characters for each control. Any of the characters in this list could be used as the new hotkey without conflicting with any existing hotkey.
Is Reference dialog needed The reference dialog does not need to be available. If it is available then for each bug discovered it is checked to see if it is a problem in the reference dialog. NOTE: Checking the reference dialog is not so exact here! Only when the equivalent controls in the reference dialog all have the hotkeys will it be reported as being in the reference also. I.e. if there are 3 controls with the same hotkey in the Localised software then those same controls in the reference dialog must have the same hotkey for it to be reported as existing in the reference also.
False positive bug reports There should be very few false positives from this test. Sometimes a control only has one or 2 characters eg “X:” and it is impossible to avoid a hotkey clash. Also for Asian languages hotkeys should be the same as the US software so probably this test should be run on those languages.
Test Identifier The identifier for this test/bug is “RepeatedHotkey”
pywinauto.tests.repeatedhotkey.
GetHotkey
(text)¶Return the position and character of the hotkey
pywinauto.tests.repeatedhotkey.
ImplementsHotkey
(win)¶checks whether a control interprets & character to be a hotkey
pywinauto.tests.repeatedhotkey.
RepeatedHotkeyTest
(windows)¶Return the repeated hotkey errors
pywinauto.tests.translation¶
Translation Test
What is checked This checks for controls which appear not to be translated.
How is it checked It compares the text of the localised and reference controls.
If there are more than string in the control then each item is searched for in the US list of titles (so checking is not order dependent). The indices for the untranslated strings are returned in a comma separated string. Also the untranslated strings themselves are returned (all as one string). These strings are not escaped and are delimited as “string1”,”string2”,...”stringN”.
When is a bug reported
If the text of the localised control is identical to the reference control (in case, spacing i.e. a binary compare) then it will be flagged as untranslated. Otherwise the control is treated as translated.Note: This is the method to return the least number of bugs. If there are differences in any part of the string (e.g. a path or variable name) but the rest of the string is untranslated then a bug will not be highlighted
Bug Extra Information The bug contains the following extra information Name Description Strings The list of the untranslated strings as explained above StringIndices The list of indices (0 based) that are untranslated. This will usually be 0 but if there are many strings in the control untranslated it will report ALL the strings e.g. 0,2,5,19,23
Is Reference dialog needed The reference dialog is always necessary.
False positive bug reports False positive bugs will be reported in the following cases. - The title of the control stays the same as the US because the translation is the same as the English text(e.g. Name: in German) - The title of the control is not displayed (and not translated). This can sometimes happen if the programmer displays something else on the control after the dialog is created.
Test Identifier The identifier for this test/bug is “Translation”
pywinauto.tests.translation.
TranslationTest
(windows)¶Returns just one bug for each control
pywinauto.tests.truncation¶
Truncation Test
What is checked Checks for controls where the text does not fit in the space provided by the control.
How is it checked There is a function in windows (DrawText) that allows us to find the size that certain text will need. We use this function with correct fonts and other relevant information for the control to be as accurate as possible.
When is a bug reported When the calculated required size for the text is greater than the size of the space available for displaying the text.
Bug Extra Information The bug contains the following extra information Name Description Strings The list of the truncated strings as explained above StringIndices The list of indices (0 based) that are truncated. This will often just be 0 but if there are many strings in the control untranslated it will report ALL the strings e.g. 0,2,5,19,23
Is Reference dialog needed The reference dialog does not need to be available. If it is available then for each bug discovered it is checked to see if it is a problem in the reference dialog.
False positive bug reports Certain controls do not display the text that is the title of the control, if this is not handled in a standard manner by the software then DLGCheck will report that the string is truncated.
Test Identifier The identifier for this test/bug is “Truncation”
pywinauto.tests.truncation.
TruncationTest
(windows)¶Actually do the test
Backend Internal Implementation modules¶
pywinauto.backend¶
后端组件存储(指向平台特定事物的链接)
- class
pywinauto.backend.
BackEnd
(name, element_info_class, generic_wrapper_class)¶Minimal back-end description (name & 2 required base classes)
- class
pywinauto.backend.
BackendsRegistry
¶Registry pattern class for the list of available back-ends
element_class
¶Return
element_info.ElementInfo
‘s subclass of the active backend
name
¶Name of the active backend
wrapper_class
¶BaseWrapper’s subclass of the active backend
pywinauto.backend.
activate
(name)¶按名称设置活动后端
Possible values of name are “win32”, “uia” or other name registered by the
register()
function.
pywinauto.backend.
element_class
()¶返回
element_info.ElementInfo
的活动后端的子类
pywinauto.backend.
name
()¶Return name of the active backend
pywinauto.backend.
register
(name, element_info_class, generic_wrapper_class)¶注册一个新的后端
pywinauto.backend.
wrapper_class
()¶返回BaseWrapper的活动后端的子类
pywinauto.element_info¶
应该处理不同后端元素的类的接口
- class
pywinauto.element_info.
ElementInfo
¶Abstract wrapper for an element
children
(**kwargs)¶返回元素的子元素
class_name
¶返回元素的类名
control_id
¶返回控件的ID
descendants
(**kwargs)¶返回元素的后代
dump_window
()¶将元素转储到一组属性
enabled
¶Return True if the element is enabled
- static
filter_with_depth
(elements, root, depth)¶返回具有相对于根的特定深度级别的过滤元素
framework_id
¶返回元素的框架
handle
¶返回元素的句柄
has_depth
(root, depth)¶如果元素具有相对于根的特定深度级别,则返回True
iter_children
(**kwargs)¶迭代元素的孩子
iter_descendants
(**kwargs)¶迭代元素的后代
name
¶Return the name of the element
parent
¶Return the parent of the element
process_id
¶Return the ID of process that controls this element
rectangle
¶Return rectangle of element
rich_text
¶返回元素的文本
set_cache_strategy
(cached)¶为元素的常用属性设置缓存策略
visible
¶如果元素可见,则返回True
pywinauto.win32_element_info¶
pywinauto.uia_element_info¶
Implementation of the class to deal with an UI element (based on UI Automation API)
- class
pywinauto.uia_element_info.
UIAElementInfo
(handle_or_elem=None, cache_enable=False)¶UI element wrapper for IUIAutomation API
automation_id
¶Return AutomationId of the element
children
(**kwargs)¶Return a list of only immediate children of the element
- kwargs is a criteria to reduce a list by process, class_name, control_type, content_only and/or title.
class_name
¶Return class name of the element
control_id
¶Return ControlId of the element if it has a handle
control_type
¶Return control type of element
descendants
(**kwargs)¶Return a list of all descendant children of the element
- kwargs is a criteria to reduce a list by process, class_name, control_type, content_only and/or title.
dump_window
()¶Dump window to a set of properties
element
¶Return AutomationElement’s instance
enabled
¶Check if the element is enabled
framework_id
¶Return FrameworkId of the element
handle
¶Return handle of the element
iter_children
(**kwargs)¶Return a generator of only immediate children of the element
- kwargs is a criteria to reduce a list by process, class_name, control_type, content_only and/or title.
name
¶Return name of the element
parent
¶Return parent of the element
process_id
¶Return ProcessId of the element
rectangle
¶Return rectangle of the element
rich_text
¶Return rich_text of the element
runtime_id
¶Return Runtime ID (hashable value but may be different from run to run)
set_cache_strategy
(cached=None)¶Setup a cache strategy for frequently used attributes
visible
¶Check if the element is visible
pywinauto.uia_element_info.
elements_from_uia_array
(ptrs, cache_enable=False)¶Build a list of UIAElementInfo elements from IUIAutomationElementArray
pywinauto.uia_defines¶
Common UIA definitions and helper functions
- class
pywinauto.uia_defines.
IUIA
¶Singleton class to store global COM objects from UIAutomationCore.dll
build_condition
(process=None, class_name=None, title=None, control_type=None, content_only=None)¶Build UIA filtering conditions
- exception
pywinauto.uia_defines.
NoPatternInterfaceError
¶There is no such interface for the specified pattern
pywinauto.uia_defines.
get_elem_interface
(element_info, pattern_name)¶A helper to retrieve an element interface by the specified pattern name
TODO: handle a wrong pattern name
pywinauto.hooks¶
内部模块¶
pywinauto.controlproperties¶
Wrap
- class
pywinauto.controlproperties.
ControlProps
(*args, **kwargs)¶包装控件从文件读取以类似于hwnd控件
HasExStyle
(exstyle)¶
HasStyle
(style)¶
WindowText
(*args, **kwargs)¶
window_text
()¶
- class
pywinauto.controlproperties.
FuncWrapper
(value)¶允许属性访问的小类返回可调用对象
pywinauto.controlproperties.
GetMenuBlocks
(ctrls)¶
pywinauto.controlproperties.
MenuBlockAsControls
(menuItems, parentage=None)¶
pywinauto.controlproperties.
MenuItemAsControl
(menuItem)¶使菜单项看起来像测试的控件
pywinauto.controlproperties.
SetReferenceControls
(controls, refControls)¶为传入的控件设置参考控件
- This does some minor checking as following:
- test that there are the same number of reference controls as controls - fails with an exception if there are not
- test if all the ID’s are the same or not
pywinauto.handleprops¶
用于从窗口句柄检索属性的函数
这些是以过程方式实现的,以便对概念开销最小的其他模块有用
pywinauto.handleprops.
children
(handle)¶将句柄列表返回给此窗口的子项
pywinauto.handleprops.
classname
(handle)¶Return the class name of the window
pywinauto.handleprops.
clientrect
(handle)¶Return the client rectangle of the control
pywinauto.handleprops.
contexthelpid
(handle)¶返回窗口的上下文帮助ID
pywinauto.handleprops.
controlid
(handle)¶返回控件的ID
pywinauto.handleprops.
dumpwindow
(handle)¶将窗口转储到一组属性
pywinauto.handleprops.
exstyle
(handle)¶返回窗口的扩展样式
pywinauto.handleprops.
font
(handle)¶将字体作为窗口的LOGFONTW返回
pywinauto.handleprops.
has_enough_privileges
(process_id)¶检查目标进程是否具有足够的权限来查询GUI操作
pywinauto.handleprops.
has_exstyle
(handle, tocheck)¶Return True if the control has extended style tocheck
pywinauto.handleprops.
has_style
(handle, tocheck)¶Return True if the control has style tocheck
pywinauto.handleprops.
is64bitbinary
(filename)¶Check if the file is 64-bit binary
pywinauto.handleprops.
is64bitprocess
(process_id)¶Return True if the specified process is a 64-bit process on x64
Return False if it is only a 32-bit process running under Wow64. Always return False for x86.
pywinauto.handleprops.
is_toplevel_window
(handle)¶Return whether the window is a top level window or not
pywinauto.handleprops.
isenabled
(handle)¶Return True if the window is enabled
pywinauto.handleprops.
isunicode
(handle)¶Return True if the window is a Unicode window
pywinauto.handleprops.
isvisible
(handle)¶Return True if the window is visible
pywinauto.handleprops.
iswindow
(handle)¶Return True if the handle is a window
pywinauto.handleprops.
parent
(handle)¶Return the handle of the parent of the window
pywinauto.handleprops.
processid
(handle)¶Return the ID of process that controls this window
pywinauto.handleprops.
rectangle
(handle)¶Return the rectangle of the window
pywinauto.handleprops.
style
(handle)¶Return the style of the window
pywinauto.handleprops.
text
(handle)¶Return the text of the window
pywinauto.handleprops.
userdata
(handle)¶Return the value of any user data associated with the window
pywinauto.xml_helpers¶
pywinauto.fuzzydict¶
Match items in a dictionary using fuzzy matching
Implemented for pywinauto.
This class uses difflib to match strings. This class uses a linear search to find the items as it HAS to iterate over every item in the dictionary (otherwise it would not be possible to know which is the ‘best’ match).
If the exact item is in the dictionary (no fuzzy matching needed - then it doesn’t do the linear search and speed should be similar to standard Python dictionaries.
>>> fuzzywuzzy = FuzzyDict({"hello" : "World", "Hiya" : 2, "Here you are" : 3}) >>> fuzzywuzzy['Me again'] = [1,2,3] >>> >>> fuzzywuzzy['Hi'] 2 >>> >>> >>> # next one doesn't match well enough - so a key error is raised ... >>> fuzzywuzzy['There'] Traceback (most recent call last): File "<stdin>", line 1, in ? File "pywinauto uzzydict.py", line 125, in __getitem__ raise KeyError( KeyError: "'There'. closest match: 'hello' with ratio 0.400" >>> >>> fuzzywuzzy['you are'] 3 >>> fuzzywuzzy['again'] [1, 2, 3] >>>
- class
pywinauto.fuzzydict.
FuzzyDict
(items=None, cutoff=0.6)¶Provides a dictionary that performs fuzzy lookup
pywinauto.actionlogger¶
pywinauto.actionlogger.
ActionLogger
¶alias of
_StandardLogger
pywinauto.actionlogger.
disable
()¶Disable pywinauto logging actions
pywinauto.actionlogger.
enable
()¶Enable pywinauto logging actions
pywinauto.actionlogger.
reset_level
()¶Reset a logging level to a default
pywinauto.actionlogger.
set_level
(level)¶Set a logging level for the pywinauto logger.
pywinauto.sysinfo¶
pywinauto.remote_memory_block¶
Module containing wrapper around VirtualAllocEx/VirtualFreeEx Win32 API functions to perform custom marshalling
- exception
pywinauto.remote_memory_block.
AccessDenied
¶Raised when we cannot allocate memory in the control’s process
- class
pywinauto.remote_memory_block.
RemoteMemoryBlock
(ctrl, size=4096)¶Class that enables reading and writing memory in a different process
Address
()¶Return the address of the memory block
CheckGuardSignature
()¶read guard signature at the end of memory block
CleanUp
()¶Free Memory and the process handle
Read
(data, address=None, size=None)¶Read data from the memory block
Write
(data, address=None, size=None)¶Write data into the memory block