使用win32com让Python和AutoIT协同工作:什么';窗户把手怎么了?

使用win32com让Python和AutoIT协同工作:什么';窗户把手怎么了?,python,autoit,pywin32,Python,Autoit,Pywin32,我有一个带有GUI界面的程序,我需要手动进行初始设置。到目前为止,AutoIt在这方面非常有用,因为它提供了非常简单的方法,甚至可以使用复杂的GUI对象(下拉列表、显示在悬停菜单上等) 然而,为了完成程序设置,我最终需要的脚本将需要传递一个大数组/变量列表-有许多不同的设置需要更改 我已经设置了使用Python脚本决定这些设置变量的逻辑。现在,我正试图找出如何让Python和AutoIt相互对话 使用Python从命令行调用自定义AutoIt脚本基本上是不可能的,因为需要传递大量的变量。感觉不太

我有一个带有GUI界面的程序,我需要手动进行初始设置。到目前为止,AutoIt在这方面非常有用,因为它提供了非常简单的方法,甚至可以使用复杂的GUI对象(下拉列表、显示在悬停菜单上等)

然而,为了完成程序设置,我最终需要的脚本将需要传递一个大数组/变量列表-有许多不同的设置需要更改

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

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

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

在AutoIt中解决这个问题的一个明显方法是使用所讨论对象的“句柄”,我相信这些句柄是某种内存地址,而不是它们的字符串标题。我猜这些都是内存地址,因为AutoIt Window Info工具在指向特定窗口/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密钥文件之外,还有其他方法调用自定义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?我可能听上去很困惑,因为所有这些在我的脑海中都不是非常清晰。

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

AutoIt有一个功能,可以将基数为16的数字“转换”为HWND对象

没错!这是关键。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在大多数情况下都是“聪明”的,可以知道该做什么,但可能库不是。

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

代码如下:

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使用高级标题匹配,这允许我们使用
[句柄:000204AC]
字符串指定窗口句柄

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


顺便说一句,我是跌跌撞撞地找到这个解决办法的。我发现,不将搜索限制在我正在寻找的特定语言上通常是有帮助的。大多数情况下,可以用不同的语言找到解决方案,可以很容易地移植到您选择的语言。

可能是类型的问题。。。我不是python用户,但是您可以对
windowHandle
变量的类型运行一些检查吗。它应该是一个整数。@Mat在Python中,
windowHandle
变量的类型是unicode字符串(例如
u'000C0326'
)。整数是否应该是十六进制(例如,
'0x000C0326'
)数字(整数形式),如果要求输出
windowHandle
变量,它会自动打印出来?是。如果您传递一个字符串,则AutoIt将尝试查找其标题与该字符串匹配的窗口。在这种情况下,我没有窗户