pywinauto:如何 select 这个对话框?使用哪种间谍工具?我需要什么信息?

pywinauto: How to select this dialog? Which spying tool to use? What information do I need on it?

如何在 7-zip "Add to Archive" 对话框的第一个字段上写 "hello"?

到目前为止,我设法使用此

触发了 7-zip (windows 64x) "Add to Archive" 对话框
from pywinauto.application import Application
app = Application().start(r"C:\Program Files-ZipzFM.exe") #set the app
app.top_window_().Edit.type_keys(r"C:\Users\me\Desktop{ENTER}") 
app.top_window_().SysListView32.Select(r'test.txt') #select files in list
app.top_window_().ToolbarAdd.TypeKeys("{ENTER}") #apply

然后我无法 select 添加到存档对话框。

1:这没有用。我猜是因为它没有找到对话框。如果是,为什么?

app.window(title_re="Add to Archive", class_name="#32770").print_control_identifiers()

2:这也没有用:

app.window(title_re="Add to Archive", class_name="#32770").Edit.type_keys("hello")

3:我尝试使用 print(app.windows())

在我的应用程序中找到所有可用的对话框

但是它打印出这个:

[<pywinauto.controls.win32_controls.DialogWrapper object at 0x0000000004033D68>, <pywinauto.controls.common_controls.ToolTipsWrapper object at 0x0000000004089128>, <pywinauto.controls.hwndwrapper.HwndWrapper object at 0x0000000004089208>, <pywinauto.controls.win32_controls.DialogWrapper object at 0x
00000000040893C8>, <pywinauto.controls.win32_controls.DialogWrapper object at 0x0000000004089390>]

我没有看到任何 "Add to Archive" windows,为什么?那些东西是什么(例如in32_controls.DialogWrapper)?

不同间谍工具的打印屏幕 对话的间谍++

spy++ 在第一个控件上(它说编辑,但是 au

inspect.exe 对话框:

我看到 7zFM.exe 使用此对话框生成了另一个进程(它甚至是另一个可执行文件!)。您需要连接到新进程。

app2 = Application().connect(path='7zG.exe', title='Add to Archive')
app2.AddToArchive.print_control_identifiers()

[编辑]

如果您打开任务管理器(Win8.1 或 Win10 上的选项卡 "Details"),您将看到进程 7zG.exe。另一种查看方式:在 Spy++ 中,当您查看 windows 层次结构时,右键单击对话框 "Add to Archive" 并选择 "Properties",然后切换到具有 ProcessID 值的选项卡(显示作为十六进制数)。比较文件管理器对话框的相似数字。存在不同的 ProcessID!

在 Inspect.exe 中您还可以看到 属性 ProcessId(== 5304 在您的屏幕截图上)。在任务管理器/详细信息/列 PID.

中找到此值

Vasily 已经回答了问题。我只是想收集评论和 latest docs) 中也提到的所有要点。 (答案以 斜体 显示)。不要犹豫,填补这个基本教程中留下的漏洞(还有几个问题),或者更正它。


1/ 我无法连接到这个对话框

app.window(title_re="Add to Archive", class_name="#32770").print_control_identifiers()

答:没成功,因为是另一个进程。所以这是一种新的应用程序(app2)。所以你需要重新连接它(有些应用程序可以为它们启动的每个 windows 启动一个新进程)。

对于某些应用,您还需要指定 "backend",默认情况下为 "win32"。如果间谍工具(cf bellow)可以在"uia"模式下看到"controls"(每个字段的名称,class,按钮......),你应该使用Application(backend='uia')

要重新连接你需要再做一次app2=Application().connect(path='7zG.exe')然后到select控制

看来你指定的东西越多连接就越容易连接。这可能就是瓦西里使用路径 + 标题的原因。我只是想证明它也只适用于标题——在这种情况下

2/ 是的,但是我怎么知道这是一个新进程?

答案:您可以在间谍工具中看到(参见 6/ 和下面的打印屏幕)。

3/ 我无法 select 在该对话框上进行控制(在字段中输入文本):

app.window(title_re="Add to Archive", class_name="#32770").Edit.type_keys("hello")

答:正常,需要先连接对话框。首先连接到 app2(参见上文)然后执行此操作:

app2.window(title_re="Add to Archive", class_name="#32770").Edit1.type_keys(r"great success!", with_spaces = True)

4/ 我试图使用 print(app.windows()) 在我的应用程序上找到所有可用的对话框,但它打印了这个(和其他奇怪的东西):

[<pywinauto.controls.win32_controls.DialogWrapper object at 0x0000000004033D68>, <pywinauto.controls.common_controls.ToolTipsWrapper object at 0x0000000004089128>, <pywinauto.controls.hwndwrapper.HwndWrapper object at 0x0000000004089208>, <pywinauto.controls.win32_controls.DialogWrapper object at 0x
00000000040893C8>, <pywinauto.controls.win32_controls.DialogWrapper object at 0x0000000004089390>]

我没有看到任何 "Add to Archive" windows,为什么?那些东西是什么(例如in32_controls.DialogWrapper)?

答案:"it returns actionable wrappers for every window"。这些字符串中的每一个都是 object 的内存位置(地址)。我不知道怎么用

您可以使用 print ([w.window_text() for w in app.windows()]) 获取一些文本(它打印 ['C:\Users\Me\Desktop\', '', '', 'M', 'Default IME'] 不知道那是什么意思。)

5/ 如果我获得了访问这些对话框和控件所需的所有信息,我真的需要打印这些对话框或控件列表吗?

我不知道。我还不完全理解打印对话框列表的必要性。但我的理解(也许)是这个控制列表提供了缩短代码的方法。例如。它给出了 AddToArchive 之类的东西。你可以写 app2.AddToArchive.

而不是写 app2.window(title_re="Add to Archive").

6/ Spy++ 和 inspect.exe 甚至不显示过程(加上第二个很重而且有错误)

答案:最好的间谍工具似乎是来自 AutoHotkey 的工具(下面是 AU3_Spy.exe 的打印屏幕)。它在一个很小的 ​​window 中显示了 name/class/process 甚至控件名称(和其他东西),而没有加载 CPU。与其他 2 个间谍工具不同,AutoHotkey 提供正确的控件名称

另请注意,控件名称从一种间谍工具更改为另一种。最准确的似乎是来自 autohotkey 的那个(到目前为止所有测试都有效)。而且它只给你需要的东西,其他的间谍工具除了你需要的东西之外会显示很多无用的东西(比如进程和控件的真实名称)

你会发现一堆间谍工具 here Acc explorer 完成得很好 Ahk(它和 spy++ 做同样的事情,但只是更好)。

(欢迎使用我的截图)


额外提示:

有没有办法缩短代码?

.window(title_re="Add to Archive", class_name="#32770")

等同于 .AddtoArchive 。所以你也可以这样写:

app2.AddtoArchive.type_keys(r"great success!", with_spaces = True)

同上其他应用程序相同:

dittoApp=Application().connect(path='Ditto.exe')
ditto_dialog=ditto.window(best_match='Ditto')

相当于:

ditto=Application().connect(path='Ditto.exe')
dittoApp.Ditto

有我可以玩的动作列表吗? 您将 here 许多可以执行的操作(在列表、按钮、编辑字段...)。

您可以使用以下方法列出 object 的所有可用方法:

print(dir(dlg_spec.wrapper_object()))

例如:

print(dir(ditto.ditto.SysListView321.wrapper_object()))

使用前需要导入pywinauto模块! 模块是您需要导入的 class(例如:pywinauto.application module) 要使用 them dont forget to import the class! Ex to use one of the method listed in the findbestmatch module,您需要:from pywinauto import findbestmatch

另一个例子:你需要 from pywinauto import keyboard 才能使用 SendKeys('^a^c')