小白进行桌面端程序自动化测试

news2024/10/2 16:24:46

步骤

 

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Automation;
using System.Windows.Forms;
using System.Windows.Input;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        private Process process;

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //打开笔记本
            process = Process.Start(@"C:\Windows\System32\notepad.exe");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //关闭笔记本
            process.Kill();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //AutomationElement表示 UI 自动化树中的一个 UI 自动化元素,并包含由 UI 自动化客户端应用程序用作标识符的值。
            //获取当前桌面的根 AutomationElement。
            AutomationElement desktop = AutomationElement.RootElement;
            //StringBuilder不在内存中创建新对象,而是动态扩展内存以容纳修改后的字符串。
            StringBuilder sb = new StringBuilder();
            //TreeScope(枚举)包含指定 UI 自动化目录树内元素的范围的值。具体参考请点击以下链接进行查看
            //TreeScope官方链接:https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.automation.treescope?view=windowsdesktop-7.0
            AutomationElementCollection topWindows = desktop.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "ApplicationFrameWindow"));//查找计算器
            for (int i = 0; i < topWindows.Count; i++)
            {
                AutomationElement topWindow = topWindows[i];
                sb.AppendLine("Name:" + topWindow.Current.Name + ";ClassName=" + topWindow.Current.ClassName);
            }
            MessageBox.Show(sb.ToString());
        }

        private void button4_Click(object sender, EventArgs e)
        {
            AutomationElement desktop = AutomationElement.RootElement;
            var calcFrame1 = desktop.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "ApplicationFrameWindow"));
            AutomationElementCollection btn2 = calcFrame1.FindAll(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "num9Button"));
            AutomationElement btn = btn2[0];
            MessageBox.Show(btn.Current.Name);
        }

        private void button5_Click(object sender, EventArgs e)
        {
            AutomationElement desktop = AutomationElement.RootElement;
            var calcFrame1 = desktop.FindFirst(TreeScope.Children,
                new PropertyCondition(AutomationElement.ClassNameProperty, "ApplicationFrameWindow"));

            Condition conditionBtn6 = new AndCondition(
                new PropertyCondition(AutomationElement.ClassNameProperty, "Button"),
                new PropertyCondition(AutomationElement.NameProperty, "六")
                );
            var btn6 = calcFrame1.FindFirst(TreeScope.Descendants, conditionBtn6);
            //InvokePattern 表示用于启动或执行单个明确操作的控件,并且这些控件在激活时不保持其状态。
            //InvokePattern.Pattern 标识 InvokePattern 控件模式。
            //InvokePattern官方链接 https://learn.microsoft.com/zh-cn/dotnet/api/system.windows.automation.invokepattern?view=windowsdesktop-7.0
            InvokePattern button6Invoke = (InvokePattern)btn6.GetCurrentPattern(InvokePattern.Pattern);
            //Invoke() 发送请求以激活控件并启动其单一、明确的操作。
            button6Invoke.Invoke();

            

            Condition conditionBtnPlus = new AndCondition(
           new PropertyCondition(AutomationElement.ClassNameProperty, "Button"),
           new PropertyCondition(AutomationElement.NameProperty, "加")
           );
            var btnPlus = calcFrame1.FindFirst(TreeScope.Descendants, conditionBtnPlus);
            InvokePattern buttonPlusInvoke = (InvokePattern)btnPlus.GetCurrentPattern(InvokePattern.Pattern);
            buttonPlusInvoke.Invoke();
        }
        private static void InvokeButton(AutomationElement e)
        {
            InvokePattern Invoke = (InvokePattern)e.GetCurrentPattern(InvokePattern.Pattern);
            Invoke.Invoke();
        }
        private static void ClickCalculatorButton(AutomationElement calcFrame1, String name)
        {
            Condition conditionBtn = new AndCondition(
               new PropertyCondition(AutomationElement.ClassNameProperty, "Button"),
               new PropertyCondition(AutomationElement.NameProperty, name)
               );
            var btn = calcFrame1.FindFirst(TreeScope.Descendants, conditionBtn);
            // MessageBox.Show(btn.Current.Name);
            if (btn == null)
            {
                throw new Exception("找不到此" + name + "的按钮");
            }
            InvokeButton(btn);
        }

        private void button6_Click(object sender, EventArgs e)
        {
            AutomationElement desktop = AutomationElement.RootElement;
            var calcFrame1 = desktop.FindFirst(TreeScope.Children,
                new PropertyCondition(AutomationElement.ClassNameProperty, "ApplicationFrameWindow"));
            ClickCalculatorButton(calcFrame1, "三");
            ClickCalculatorButton(calcFrame1, "乘以");
            ClickCalculatorButton(calcFrame1, "五");
            ClickCalculatorButton(calcFrame1, "五");
            ClickCalculatorButton(calcFrame1, "等于");
        }

        [DllImport("user32.dll")]
        public static extern void SetCursorPos(int x, int y);

        [DllImport("user32.dll")]
        public static extern void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo);


        private void button7_Click(object sender, EventArgs e)
        {
            AutomationElement desktop = AutomationElement.RootElement;
            var calcFrame1 = desktop.FindFirst(TreeScope.Children,
                new PropertyCondition(AutomationElement.ClassNameProperty, "ApplicationFrameWindow"));

            Condition conditionBtn6 = new AndCondition(
                new PropertyCondition(AutomationElement.ClassNameProperty, "Button"),
                new PropertyCondition(AutomationElement.NameProperty, "六")
                );
            var btn6 = calcFrame1.FindFirst(TreeScope.Descendants, conditionBtn6);

            SetCursorPos((int)btn6.GetClickablePoint().X, (int)btn6.GetClickablePoint().Y);
            mouse_event(0x0002, 0, 0, 0, 0);  // 模拟鼠标左键按下
            mouse_event(0x0004, 0, 0, 0, 0);  // 模拟鼠标左键弹起

        }

       
    }
}

各按钮的功能展示

按钮1

按钮2

按钮3

修改对应代码,每个按钮点击事件下的的该属性都需要进行修改

 结果

按钮4

 结果

按钮5

按钮6

 按钮7

功能是让鼠标去点击,实现点击按钮的功能

 

参考

https://www.cnblogs.com/baihuitestsoftware/articles/9047705.html

UI自动化 --- 微软UI Automation_dotNET跨平台的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/865067.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Vue 3.0中的Treeshaking?

1.treeshaking是什么&#xff1f; Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术&#xff0c;专业术语叫 Dead code elimination 简单来讲&#xff0c;就是在保持代码运行结果不变的前提下&#xff0c;去除无用的代码 如果把代码打包比作制作蛋糕&#…

视觉学习(七)---Flask 框架下接口调用及python requests 实现json字符串传输

在项目实施过程中需要与其他系统进行接口联调&#xff0c;将图像检测的结果传递给其他系统接口&#xff0c;进行逻辑调用。这中间的过程可以通过requests库进行实现。 1.安装requests库 pip install requests2.postman 接口测试 我们先通过postman 了解下接口调用&#xff0…

指针的一些笔试题

一&#xff1a; 二&#xff1a; 三&#xff1a; 四&#xff1a; 五&#xff1a; 六 七 八&#xff0c;printf对指针的 --操作是会改变pcc的&#xff0c;要继承&#xff0c;而单纯的数子&#xff0c;是不会改变原有位置的

酒吧座位全解析 小白必看

相信还有很多第一次去酒吧的朋友们还不了解吧台、散台、卡座的区分&#xff0c;下面我简单解说一下&#xff0c;如有错漏&#xff0c;欢迎指正&#xff01;一、吧台吧台是酒吧的核心部位&#xff0c;走进酒吧门&#xff0c;首先映入眼帘的就是吧台&#xff0c;一排人围着吧台几…

Qt 7. 在自定义类TcpClient类中使用信号槽功能

1. 因为只有QObject类及其子类派生的类才能使用信号和槽机制。 使用信号和槽还必须在类声明的最开始处添加Q_OBJECT宏&#xff0c;在这个程序中&#xff0c;类的声明是自动生成的&#xff0c;已经添加了这个宏。UI类继承自QDialog&#xff0c;QDialog类又继承自QWidget类&…

【果树农药喷洒机器人】Part7:果树对靶变量喷药实验

文章目录 一、引言二、果树对靶变量喷药实验2.1实验准备2.2实验步骤2.3实验结果与分析总结 一、引言 对靶不变量喷药指视觉系统识别出树冠后对其喷药&#xff0c;而不将树冠间隙作为喷施对象&#xff0c;为间歇性喷药模式&#xff0c;有别于连续喷药对非靶标和靶标均进行的无差…

绝了!学编程的还有不知道的吗?这个Java开发工具免费了!

智能开发正在迅速走红&#xff01; 随着ChatGPT的广泛应用&#xff0c;智能开发越来越受到关注。然而&#xff0c;实际上&#xff0c;在数年前开始尝试智能开发的探索。 自从2014年ForresterResearch提出"低代码"的概念以来&#xff0c;低代码平台的发展非常迅速。…

Nginx之lnmp架构

目录 一.什么是LNMP二.LNMP环境搭建1.Nginx的搭建2.安装php3.安装数据库4.测试Nginx与PHP的连接5.测试PHP连接数据库 一.什么是LNMP LNMP是一套技术的组合&#xff0c;Llinux&#xff0c;Nnginx&#xff0c;Mmysql&#xff0c;Pphp 首先Nginx服务是不能处理动态资源请求&…

2.物联网LWIP网络

一。创建工程 1.Cubemx创建工程 &#xff08;1&#xff09;操作系统的时钟配置 &#xff08;2&#xff09;配置ETH 注意&#xff1a;根据底板原理图&#xff0c;不是核心板原理图 &#xff08;3&#xff09;配置USART1串口&#xff0c;配置为异步通信 注意&#xff1a;配置结…

一篇文章带你实现栈的接口

一&#xff0c;什么是栈 栈&#xff08;Stacks&#xff09;是限定在一端插入和删除的线性表。允许插入和删除的一端称为栈顶&#xff08;Top&#xff09;&#xff0c;另一端称为栈底&#xff08;Bottom&#xff09;。栈中的数据元素遵守后进先出&#xff08;Last In First Out…

Mysql索引篇——Day01

Mysql索引篇——Day01 什么是索引&#xff1f;索引的分类按数据结构分按物理存储分按字段特性分类按字段个数分类 什么时候需要创建索引/不需要创建索引&#xff1f;优化索引的方法前缀索引优化覆盖索引优化主键索引最好是自增的索引最好设置为 NOT NULL防止索引失效 什么是索引…

Java基础入门篇——Java Number Math 类

当我们在Java中处理数字和执行数学计算时&#xff0c;可以使用Java的Number和Math类。这两个类提供了一系列方法和常量&#xff0c;用于处理和操作数字数据。 1、Number类&#xff1a; Number是一个抽象类&#xff0c;是Java中所有数字类的父类&#xff0c;包括Byte、Short…

设计模式(6)原型模式

一、介绍 Java中自带的原型模式是clone()方法。该方法是Object的方法&#xff0c;native类型。他的作用就是将对象的在内存的那一块内存数据一字不差地再复制一个。我们写简单类的时候只需要实现Cloneable接口&#xff0c;然后调用Object::clone方法就可实现克隆功能。这样实现…

1.物联网IWIP网络

一。以太网 1.nc模拟UDP &#xff08;1&#xff09;COMMBOX通信调试工具 &#xff08;2&#xff09; 控制台输入nc -u 127.0.0.1 8000,此时串口也可以获得数据 &#xff08;3&#xff09;串口调试程序发送字符串&#xff0c;电脑控制台也会展示同样字符串&#xff08;说明UDP…

java文件

一.File类 二.扫描指定目录&#xff0c;并找到名称中包含指定字符的所有普通文件&#xff08;不包含目录&#xff09;&#xff0c;并且后续询问用户是否要删除该文件 我的代码: import java.io.File; import java.io.IOException; import java.util.Scanner;public class Tes…

对于msvcr120.dll丢失的问题,分享几种解决方法

msvcr120.dll的作用是提供一系列的运行时函数和功能&#xff0c;以便应用程序能够正常运行。这些函数和功能包括内存管理、异常处理、输入输出操作、数学运算等。在没有这个库文件的情况下&#xff0c;应用程序可能无法正常启动或执行特定的功能&#xff0c;甚至会出现错误提示…

Spring MVC【一篇搞定】

Spring MVC 文章目录 Spring MVC一、什么是 Spring MVC二、介绍MVC2.1、Spring MVC 和 MVC 之间的关系 三、创建 Spring MVC四、掌握 Spring MVC 的核心 ☆☆☆☆4.1、Spring 热部署4.2、实现用户与程序的连接 ☆4.2.1、RequestMapping4.2.2、GetMapping/PostMapping 4.3、获取…

《Zookeeper》源码分析(七)之 NIOServerCnxn的工作原理

目录 NIOServerCnxnreadPayload()handleWrite(k)process() NIOServerCnxn 在上一节IOWorkRequest的doWork()方法中提到会将IO就绪的key通过handleIO()方法提交给NIOServerCnxn处理&#xff0c;一个NIOServerCnxn代表客户端与服务端的一个连接&#xff0c;它用于处理两者之间的…

JavaScript 中 let 和 var 的区别

首先&#xff0c;let 和 var 都是用于声明变量的关键字&#xff0c;在老版 JavaScript 中也许你会见到 var 方式来声明变量&#xff0c;而现如今几乎都是使用 let 进行声明&#xff0c;接下来看看这两个关键字之间的区别。 1、作用域 var var 声明的变量在函数内部有效&#x…

【什么是应变波齿轮又名谐波驱动?机器人应用的完美齿轮组!?】

什么是应变波齿轮又名谐波驱动&#xff1f;机器人应用的完美齿轮组&#xff01;&#xff1f; 1. 什么是应变波齿轮&#xff1f;2. 工作原理3. 应变波齿轮 – 谐波驱动 3D 模型4. 3D 打印应变波齿轮 – 谐波驱动5. 总结 在本教程中&#xff0c;我们将学习什么是应变波齿轮&#…