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

Bro*_*ion 13 vb.net autoit ui-automation

设置环境:

我正在使用vb.net开发一个带有.NET Framework 4的Windows窗体应用程序.


我的目标:

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

我不想使用SendKeys作为方法.


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

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


有人可以提供一个关于如何接近这个的指针吗?我真的很感激.

Bro*_*ion 17

我的解决方案

我尝试了两种方法:

AutoIt是我使用的,因为它对我的特定应用程序更可靠.

但是,Windows UI也可以正常工作.这是两种解决方案.


使用Windows UI自动化的步骤:

  • 使用Spy ++识别按钮的控件ID
  • 添加对UIAutomationClient和的引用UIAutomationTypes
  • 设置aeDesktop为根ae元素并调用按钮单击

WindowsUI参考

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
Run Code Online (Sandbox Code Playgroud)



使用AutoIt的步骤:

  • 识别按钮的ClassnameNN
  • 获取calc.exe的句柄
  • 使用ControlClick功能单击按钮

Finder工具


如果使用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
Run Code Online (Sandbox Code Playgroud)


感谢您在评论中提供的所有帮助和建议.它帮助极大.