如何使用 AutoIt 或 Windows UI 自动化单击应用程序中的按钮

Posted

技术标签:

【中文标题】如何使用 AutoIt 或 Windows UI 自动化单击应用程序中的按钮【英文标题】:How to click buttons in an application using AutoIt or Windows UI Automation 【发布时间】:2014-04-28 09:38:40 【问题描述】:

设置环境:

我正在使用 vb.net 使用 .NET Framework 4 开发 Windows 窗体应用程序。

我的目标:

    使用Process.Start打开calculator.exe 使用所有vb.net代码,可以点击5 + 5 =

我不想使用 SendKeys 作为方法。

经过研究,这个链接提供了一个良好的开端:

本教程(用 C# 编写)与我尝试使用 vb.net 所做的非常相似:

How to click a button in another application

有人可以提供有关如何解决此问题的指针吗?我真的很感激。

【问题讨论】:

你太努力了。只需使用 UI Automation 代替。额外的好处:在非英语版本的 Windows 上(如您提出的解决方案),使用 UI 自动化(正确)不会失败。 一个窗口类和一个控件 ID 是不相关的,所以你用 00000079 调用的 FindWindowEx 没有意义。我可能会解释如何获得= 按钮,但我敢打赌,您不想在最终代码中定位 calc.exe。您要点击哪种外部应用程序? 不点击=,不如直接使用SendKeys发送ENTER键? 很多微软程序都有DLL文件,你可以在项目中引用来运行它们的功能 【参考方案1】:

我的解决方案:

我尝试了两种方法:

Windows UI Automation AutoIt

我之所以使用 AutoIt,是因为它对我的特定应用程序更可靠。

不过,Windows UI 也能正常工作。以下是两种解决方案。

使用 Windows UI 自动化的步骤

使用 Spy++ 识别按钮的控件 ID 添加对UIAutomationClientUIAutomationTypes 的引用 将aeDesktop 设置为根ae 元素并调用按钮点击

Imports System.Windows.Automation
Imports System.Threading
Imports System.Diagnostics

Public Class Form1

    Private aeDesktop As AutomationElement
    Private aeCalculator As AutomationElement

    Private ae5Btn As AutomationElement
    Private aeAddBtn As AutomationElement
    Private aeEqualsBtn As AutomationElement

    Private p As Process

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

        Try

            'Set reference to the root ae element - the desktop
            aeDesktop = AutomationElement.RootElement

            'Launch Calculator application 
            p = Process.Start("C:\Windows\System32\calc.exe")

            '**********  Keep looping while waiting to get the reference to the "Calculator" on Desktop ************************************

            Dim numwaits As Integer = 0

            Do
                Debug.WriteLine("Looking for Calculator . . . ")
                aeCalculator = aeDesktop.FindFirst(TreeScope.Children, New PropertyCondition(AutomationElement.NameProperty, "Calculator"))
                numwaits += 1
                Thread.Sleep(100)

            Loop While aeCalculator Is Nothing AndAlso numwaits < 50

            If aeCalculator Is Nothing Then
                Throw New Exception("Failed to find Calculator")
            Else
                Debug.WriteLine("Found the Calculator Application!")
            End If

            '*********************************************************************************************************************************


            'NOTE: In spy++ Controlids are represented as hex (i.e. 00000087) - need to convert these to decimal (i.e. 135)

            '`5` btn
            '00000087 ---> 135
            Dim btn5hexID As String = "00000087"
            Dim btn5decimalID As String = Convert.ToInt32("00000087", 16).ToString

            '`+` btn
            '0000005D ---> 93
            Dim btnAddhexID As String = "0000005D"
            Dim btnAdddecimalID As String = Convert.ToInt32("0000005D", 16).ToString

            '`=` btn
            '00000079 ---> 121
            Dim btnEqualshexID As String = "00000079"
            Dim btnEqualsdecimalID As String = Convert.ToInt32("00000079", 16).ToString


            'Set reference for the `5` Button
            ae5Btn = aeCalculator.FindFirst(TreeScope.Descendants, New PropertyCondition(AutomationElement.AutomationIdProperty, btn5decimalID))

            'Set reference for the `+` Button
            aeAddBtn = aeCalculator.FindFirst(TreeScope.Descendants, New PropertyCondition(AutomationElement.AutomationIdProperty, btnAdddecimalID))

            'Set reference for the `=` Button
            aeEqualsBtn = aeCalculator.FindFirst(TreeScope.Descendants, New PropertyCondition(AutomationElement.AutomationIdProperty, btnEqualsdecimalID))


            'Manipulate calculator application by using invoke method to click on buttons
            Dim ipClick5Btn As InvokePattern = DirectCast(ae5Btn.GetCurrentPattern(InvokePattern.Pattern), InvokePattern)
            Dim ipClickAddBtn As InvokePattern = DirectCast(aeAddBtn.GetCurrentPattern(InvokePattern.Pattern), InvokePattern)
            Dim ipClickEqualsBtn As InvokePattern = DirectCast(aeEqualsBtn.GetCurrentPattern(InvokePattern.Pattern), InvokePattern)

            'Click 5
            ipClick5Btn.Invoke()

            'Click +
            ipClickAddBtn.Invoke()

            'Click 5
            ipClick5Btn.Invoke()

            'Click =
            ipClickEqualsBtn.Invoke()

            'Now calculator should display 10 as a result


            'Wait two seconds before closing
            Thread.Sleep(2000)

            'Exit Calculator
            p.CloseMainWindow()



        Catch ex As Exception

            'Handle any exceptions
            Debug.WriteLine("Fatal error: " & ex.Message)

        End Try

    End Sub

End Class

使用 AutoIt 的步骤

识别按钮的类名NN 获取 calc.exe 的句柄 使用ControlClick函数点击按钮

如果使用 AutoIt,请选择完整安装并下载脚本编辑器。粘贴代码,它应该可以工作。

Download AutoIt

;Open up Calculator
Run('calc.exe')

;Pause execution until Calculator becomes active window
WinWaitActive('Calculator')

;Get the handle for Calculator
$hWnd = WinGetHandle('Calculator')

;Using the `Finder Tool`, you can drag and drop it onto controls to see all information (i.e. Text, Class, Handle, etc.)

;`ClassnameNN: Button10` is the number 5
;`ClassnameNN: Button23` is the addition operator (+)
;`ClassnameNN: Button28` is the equals operator (=)

;***** simple operation will perform 5 + 5 = 10 **************

;click 5
ControlClick($hWnd, "", "[CLASSNN:Button10]")

;click +
ControlClick($hWnd, "", "[CLASSNN:Button23]")

;click 5
ControlClick($hWnd, "", "[CLASSNN:Button10]")

;click =
ControlClick($hWnd, "", "[CLASSNN:Button28]")

;calculator should now display 10 as a result

;************************************************************

;Wait 2 seconds to show result
Sleep(2000)

;Close Calculator
WinClose($hWnd)

Exit

感谢您在 cmets 中提供的所有帮助和建议。它帮助很大。

【讨论】:

以上是关于如何使用 AutoIt 或 Windows UI 自动化单击应用程序中的按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 AutoIt 在 Windows 资源管理器中右键单击文件

如何避免windows系统开机启动每次都弹出AutoIt报错

初识AutoIt

自动化之UI(autoit)

jmeter结合autoit操作windows程序

selenium使用autoit3处理windows控件