python - 使用 win32com : what's up with those window handles? 让 Python 和 AutoIT 协同工作

标签 python autoit pywin32

我有一个带有 GUI 界面的程序,我需要手动进行初始设置。到目前为止,AutoIt 对此非常有帮助,因为它提供了非常简单的方法来处理复杂的 GUI 对象(下拉列表、悬停菜单等)。

但是,为了进行程序设置,我最终需要的脚本将需要传递一个大型数组/变量列表 - 需要很多不同的设置被改变。

我已经使用 Python 脚本设置了决定这些设置变量的逻辑。现在我想弄清楚如何让 Python 和 AutoIt 相互交谈。

使用 Python 从命令行调用自定义 AutoIt 脚本基本上是不可能的,因为需要传递大量变量。感觉不好看我可以尝试让 Python 编写一个 AutoIt“ key 文件”,然后 AutoIt 可以读取该文件以设置其初始变量,但我想确保我已经用尽了 Python 的所有选项,以便首先直接与 AutoIt 一起工作。

为此,我一直在尝试使用 Python 和 win32com 库来与 AutoIt 交互。事情似乎运作良好 - 只要我通过字符串标题而不是它们的(内存?)句柄引用窗口/菜单/对象。这是有问题的,因为我的设置脚本可能并行运行,同时设置两个或多个单独的文件。如果是这种情况,同时在每个文件中打开一个标题字符串为“打开文件...”的框可能会造成混淆。

在 AutoIt 中解决这个问题的明显方法是使用相关对象的“句柄”,我认为这是某种内存地址,而不是它们的字符串标题。我猜这些是 AutoIt 窗口信息工具的内存地址,当指向特定的窗口/GUI 对象选项时,会列出一个十六进制数作为对象的句柄值。

AutoIt 有一套函数可以获取窗口、菜单等的句柄。它们在 AutoIt COM dll 中实现,但我无法让它们在 Python 中工作。句柄函数在 Python 中返回一个 unicode 对象,而不是 AutoIt 中的十六进制字符串。我认为这就是为什么尝试在 Python 中使用这个“句柄”的函数不起作用的原因。

例子:

autoIt = win32com.client.Dispatch("AutoItX3.Control")
windowHandle = autoIt.WinGetHandle(knownWindowTitle)
returnedWindowTitle = autoIt.WinGetTitle(windowHandle)

通常,returnedWindowTitle 和 knownWindowTitle 不匹配,因为 returnedWindowTitle 似乎总是“0”。这里发生了什么?

除了使用 win32com、命令行或使用 AutoIt key 文件之外,还有其他方法可以让我调用自定义 AutoIt 函数吗?

感谢您的帮助。

编辑:我忘了说 unicode 字符串实际上与我在 AutoIt 中打印句柄变量时得到的十六进制数相匹配。

例如,在 Python 中,handle 变量在打印出来时会给出 u'000C0326'。在 AutoIt 中,它给了我“0x000C0326”。

编辑:根据 Mat 的建议进行的一些试验:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control")
In: mainWindowTitle = "Untitled"
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle)
In: mainWindowHandle
Out: u'000204AC'
In: testHandle = int(mainWindowHandle, 16)
In: testHandle
Out: 132268
In: autoIt.WinGetTitle(testHandle)
Out: u'0'

编辑:我发现了窗口句柄对象的类型:它是一个 Microsoft HWND 对象。 AutoIt 有一个函数可以将 16 进制数“转换”为 HWND 对象(即找到具有该 16 进制数内存/句柄/等的 HWND 对象)。我很幸运,他们没有将该功能放入 AutoItX(COM dll)中。所以,如果我真的想运行它,我将不得不尝试弄清楚如何返回由 16 进制地址指向的任何对象,然后以正确的方式将它传输到 AutoItX?我可能听起来很困惑,因为现在我脑子里还不是很清楚所有这些。

最佳答案

为了便于搜索,我将发布我找到的解决方案。

代码如下:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control")
In: autoIt.AutoItSetOption("WinTitleMatchMode", 4)
In: mainWindowTitle = "Untitled"
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle)
In: mainWindowHandle
Out: u'000204AC'
In: testHandle = "[HANDLE:%s]" % mainWindowHandle
In: autoIt.WinGetTitle(testHandle)
Out: u'Untitled - Notepad'

autoIt.AutoItSetOption("WinTitleMatchMode", 4) 告诉 autoit 使用高级标题匹配,这允许我们使用 [HANDLE:000204AC] 指定窗口句柄字符串。

这里不需要实际的窗口句柄。

顺便说一句,我偶然发现了这个解决方案 this forum post .我发现不将我的搜索限制在我正在寻找的特定语言通常是有帮助的。大多数情况下,可以找到不同语言的解决方案,可以轻松移植到您选择的语言。

关于python - 使用 win32com : what's up with those window handles? 让 Python 和 AutoIT 协同工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8844279/

相关文章:

python - 树莓派 GUI 上的 QT 创建者

python - 使用 Lambda 函数在 S3 中创建并上传文件

python - 将 json.dump 移植到 StringIO 代码到 python 3

function - 在 AutoIT 中将函数作为参数传递

Python更改屏幕分辨率虚拟机

python - 在 Python 中管理实例

windows - 打印到控制台/命令提示符

c++ - AutoIt 和 C++。统一码

python - 使用 pywin32 在 Excel 中写入日期而无需时间

python - 是否可以在 python 中获取事件窗口的当前插入点(文本光标/插入符)?