AutoIT或User32按钮偶尔点击工作
本文关键字:工作 偶尔 按钮 User32 AutoIT | 更新日期: 2023-09-27 18:24:00
我正在尝试自动化应用程序的测试,但我遇到了一个难以解决的问题。
该应用程序有标准的窗口按钮,我已经尝试过使用AutoIT和User32 dll来单击其中的一些按钮。有时按钮点击正确(耶!),有时失败(boo!)-但更糟糕的是,AutoIT确信点击了按钮(双boo。当我看到它被说服时,我的意思是它会返回点击成功,而不是。
我在Win Server 2K8上运行该应用程序,除了使用MDI窗口外,该应用程序没有什么特别之处,并且一些按钮包含在MDI窗口中。但是,有些不在MDI窗口中(例如,在创建父窗口之前的登录窗口)。
这是我的命令顺序:
在窗口中找到按钮(总是成功)将窗口置于前台(成功)激活窗口(成功)激活按钮(成功)聚焦按钮(成功)如果按钮被聚焦,并且按钮被启用,那么点击它。(成功/失败,不可预测的行为。我无法缩小它为什么有时成功,为什么有时失败…)
其他详细信息:
有时,订单中有一个按钮被点击,它应该会打开另一个窗口。该窗口被关闭,然后再次单击按钮——这一次,什么都没发生。其他时候,它会像预期的那样工作。
我以管理员身份运行,UAC已完全禁用。
据我所知,这不是一个时间问题,因为我确实确保按钮是聚焦的,并在尝试点击它之前启用,我看到按钮周围确实有聚焦的高亮显示
正如我所提到的,我也一直在尝试使用一个简单的User32/SendMessage调用,但这也失败了。
最后,但同样重要的是,当我手动与应用程序交互时,这种情况不会发生。我一直有实际的按钮点击工作。
有什么想法吗?
更新
这是我应该提到的等式的另一个变量——这发生在VM上(因为这是我需要运行它的地方)。我可以在自己的机器上进行一些有限的测试,但要进行真正的测试,需要在虚拟机上进行。点击我自己的开发框似乎是可靠的,这让这一切变得更加令人困惑。
我一直在另一个虚拟机上尝试这个,它似乎也在那里工作。就两个虚拟机而言,它们运行的是相同版本的Windows、相同版本的应用程序和相同版本的AutoIT等。
我已经把它简化为一个细节——幸运的是,我无法配置自己,必须填写一张更改任何配置的票证。配置的不同之处在于:
在不工作的虚拟机上,设备管理器显示一个鼠标,它是vmware鼠标。在工作的虚拟机上,设备管理器显示一个PS/2鼠标。显然,两者都是软件鼠标,但我现在想知道VMWare鼠标是否会有不同的行为,并导致按钮点击不总是起作用。我不确定这种解决方案的可能性有多大,因为根据我的理解,使用User32 SendMessage调用实际上并没有使用鼠标,而是发送与鼠标本应发送的消息相同的消息,但值得一试。。。
您说您已经成功地按下了Focus
按钮,那么您是否尝试发送Spacebar
事件而不是MouseClick
?
Send("{SPACE}")
(我想这就是语法。我不是一个AutoIt的常客)
空格键通常可用于与大多数可点击控件交互,如按钮和复选框。根据我的经验,由于奇怪、不一致的原因,模拟鼠标点击,甚至ControlClicks
,都远不如按键可靠。我深表同情。
至于检测按钮是否被点击,也许最简单的方法是让按钮更改AutoIT
可以检测到的形式。例如,显示Ready
的状态标签,直到用户按下按钮。当用户按下按钮时,文本将变为Processing
。如有必要,您可以使标签不可见(或位于表单边界之外),这样用户就看不到它,但AutoIt可以。
当你发布这个问题时,你可能已经成功地解决了这个问题,但还没有好的答案,所以我将发布我的:
我在运行Windows Server 2008 R2的虚拟机上遇到了同样的问题:我无法通过Win32 API SendMessage向特定程序(及其主窗口)发送击键或执行任何操作。
根据这个问答,这是一个UIPI问题(自Windows Vista以来一直存在)。您应该简单地关闭UAC来解决这个问题。我测试了它,它有效。通过我提供的链接可以找到更多的替代方案。
我模拟了您的情况,它在Windows7上100%工作:
using System.Runtime.InteropServices;
[DllImport("user32.dll", SetLastError = true)]
static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
void ClickFocusedControl()
{
const uint KEYEVENTF_EXTENDEDKEY = 0x1;
const uint KEYEVENTF_KEYUP = 0x2;
keybd_event(13, Convert.ToByte(0), KEYEVENTF_EXTENDEDKEY, UIntPtr.Zero); //Generates a KEY_DOWN
keybd_event(13, Convert.ToByte(0), KEYEVENTF_KEYUP, UIntPtr.Zero); // Generates a KEY_UP
}