使用win32com让Python和AutoIT协同工作:那些窗口句柄是怎么回事?

2024-10-01 17:35:57 发布

您现在位置:Python中文网/ 问答频道 /正文

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

但是,为了完成程序设置,我最终需要的脚本需要传递一个大数组/变量列表-有一批不同设置的需要更改。在

我已经设置了使用Python脚本决定这些设置变量是什么的逻辑。现在我正试图找出如何让Python和AutoIt相互通信。在

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

为此,我一直在尝试使用Python和win32com库来与AutoIt接口。只要我引用窗口/菜单/对象的字符串标题而不是它们的(内存?)就可以了把手。这是个问题,因为我的设置脚本可能并行运行,同时设置两个或多个单独的文件。如果是这样的话,在每个文件中同时打开一个标题字符串为“openfile…”的框可能会混淆一些事情。在

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

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

示例:

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

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

除了使用win32com、命令行或AutoIt keyfile之外,还有其他方法调用自定义AutoIt函数吗?在

谢谢你的帮助。在

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

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

编辑:基于Mat建议的一些试验:

^{pr2}$

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


Tags: 文件对象方法函数字符串脚本标题菜单
2条回答

为了搜索,我会把我找到的解决方案贴出来。在

代码如下:

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上遇到了这个问题。我发现,不把搜索限制在我要查找的特定语言上通常是有帮助的。大多数情况下,可以用另一种语言找到解决方案,这种语言可以很容易地移植到您选择的语言中。在

窗口句柄的类型是字符串。原因是WinList同时返回窗口句柄和窗口标题。标题不能放入句柄类型,但句柄可以放入字符串类型(对于标题)。我的猜测是,他们采用了这种设计理念,并将其应用于其他功能。如果您查看wingthandle的文档,它会告诉您句柄的返回类型:它是一个字符串。在

AutoIt has a function that can "convert" a base 16 number into an HWND object.

没错!这是关键。AutoIt为你做这件事。您试图将句柄转换为对AutoIt有用的东西,但是AutoIt已经可以使用存储为字符串的句柄。在

你的测试应该是:

In: autoIt = win32com.client.Dispatch("AutoItX3.Control")
In: mainWindowTitle = "Untitled"
In: mainWindowHandle = autoIt.WinGetHandle(mainWindowTitle)
In: mainWindowHandle
Out: u'000204AC'
In: autoIt.WinGetTitle(mainWindowHandle)
Out: u'Untitled - Notepad'

如果要在其他库中使用该句柄,可能会遇到一些问题。我建议你试着像在测试中那样解析这个数字,然后把它传递出去。AutoIt足够聪明,在大多数情况下都能弄清楚该怎么做,也许图书馆没有。在

相关问题 更多 >

    热门问题