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

标签 vb.net ui-automation autoit

安装环境:

我正在使用 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


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

    最佳答案

    我的解决方案:

    我尝试了两种方法:

  • Windows UI Automation
  • AutoIt

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

    但是,Windows UI 也能正常工作。这里有两个解决方案。

    使用 Windows UI 自动化的步骤 :
  • 使用 Spy++ 识别按钮的控件 ID
  • 添加对 UIAutomationClient 的引用和 UIAutomationTypes
  • 套装aeDesktop作为根 ae 元素和调用按钮单击

  • WindowsUI References
    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 时的步骤 :
  • 识别按钮的 ClassnameNN
  • 获取 calc.exe 的句柄
  • 使用 ControlClick单击按钮的功能

  • Finder Tool

    如果使用 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
    

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

    关于vb.net - 如何使用 AutoIt 或 Windows UI 自动化单击应用程序中的按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22551669/

    相关文章:

    vb.net - 具有多个输出的 VB 函数

    java - 我在客户端上没有收到来自服务器的消息

    java - 使用 selenium webdriver 获取占位符文本颜色

    iOS 系统权限警报 View 未显示在对象浏览器中

    powershell - 如何为 AutoIt 和 PowerShell 获得相同的 base64 编码?

    c++ - 为什么我在 dll 中的 mousehook 无法识别简单的 BOOL?

    vb.net - 从 linq (vb.net 3.5) 中的数据行中选择两个数据列

    regex - 替换除指定字符的最后一个实例以外的所有实例

    ios - Xcode INSTRUMENTS 通过/失败日志记录功能在 Xcode 4.6 中似乎已损坏

    java - 在 Java 中使用 ImageSearchDll.dll(来自 AutoIt)编辑 : JNA