• "拍牌神器"是怎样炼成的(二)--- 键鼠模拟之AutoIt


    不同于上一篇的WinAPI方法,这次让我们来看另一个更简单、有效的键鼠模拟方案,即通过COM组件AutoItX实现键鼠模拟。

    AutoIt

    AutoIt是一个免费软件,它使用一种类似BASIC的脚本语言,对Windows图形界面进行自动操控。它的网址是http://www.autoitscript.com

    本次我们不讨论它的脚本语言,而是在C#中使用其COM组件来完成键鼠模拟的工作,在开始之前,先归纳一下下AutoIt官网上介绍的主要功能:

    • 模拟键盘、鼠标操作。
    • 与Windows的标准控件进行交互。
    • 操控Windows窗口和进程。
    • 支持脚本编程,并能将脚本编译成独立的EXE文件。
    • 支持COM组件。

    了解了AutoIt,让我们继续拿上海拍牌程序(NetBidClient)作为实验对象,用C#调用AutoItX组件进行拍牌出价的操作。

    目标

    本次我们的实验目标是让计算机在拍牌的第二阶段自动出价,帮我们在最低可成交价的基础上加价900元出价。具体一点的目标如下:

    • 点“+300”按钮(模拟鼠标输入方式)。
    • 读取价格输入框(TextBox)中的值,在此基础上加价600元写回价格框(发送消息方式)。
    • 点“自动查询公开信息”复选框(控制标准控件)。
    • 点“出价”按钮,打开验证码窗口。

    目标

    准备工作

    • 下载并安装 AutoIt v3。
    • 配置拍牌程序(NetBidClient)的演示环境(参考上一篇---键鼠模拟之WinAPI)。
    • 练习使用"AutoIt Window Info"工具抓取窗口控件。

      这个工具类似VS中的Spy++, 只是设计得更适合AutoIt脚本使用,界面如下图:

    AutoIt

    绿圈中的十字准星用法和Spy++中的一样,拖到控件上就能捕获控件信息(只能是标准控件)。

    红线标注的部分是我们常用的信息,可能是你调用AutoItX函数时需要传入的参数,或者是用来计算坐标等,如Advanced Mode 属性值 [CLASS:TNoPasteEdit; INSTANCE:2] 用于控件在窗体中的唯一标识。

    新建工程、添加引用

    新建一个WinForm工程,并为工程添加AutoItX的COM组件引用如下图:

    引用

    接下来,需要设置一下工程属性,因为AutoItX是32位的组件,所以我们的工程也得是32位的,在资源管理器窗口中鼠标右键选中工程,依次工程->属性->生成->目标平台->x86

    在代码中添加using引用指令,就可以使用它的丰富功能了。

    using AutoItX3Lib;
    
    AutoItX3 _V3 = null;
    _V3 = new AutoItX3(); //实例化
    

    使用参数设置

    通过调用AutoItSetOption函数可以对AutoIt实例进行参数设置,这些参数内容可在AutoIt的帮助文档中找到,主要是些关于坐标系统、操作延时、窗口信息查询的匹配模式等等内容, 你可以根据实际情况选择设置,不设也没有问题,它们有默认值,看两个例子:

    // 匹配窗体标题时,只要含有指定的字符串即可
    // default=1 是开头部分与指定的字符串匹配
    // 也可以用高级模式 = 4, 还能通过正则表达式匹配标题
    _V3.AutoItSetOption("WinTitleMatchMode", 2);
    
    //设置鼠标点击的延时,连续点2次鼠标时的时间间隔(ms),默认是 10ms
    _V3.AutoItSetOption("MouseClickDelay", 20);
    

    模拟鼠标键盘输入

    在AutoItX中有一些以Mouse*开头的函数用于模拟鼠标输入,如 MouseClick,MouseDown,MouseUp,MouseMove,MouseWheel,MouseClickDrag,这些函数的调用大同小异,现在我们以MouseClick为例进行说明:

    MouseClick ( "button" [, x, y [, clicks = 1 [, speed = 10]]] )

    • button: 指鼠标键(如 left,right,middle... 具体参见帮助)
    • x,y: 指鼠标点击的坐标, 这里是屏幕坐标。
    • clicks: 点击的次数
    • speed: 鼠标移动的速度 (1-100,1最快),若为0 则立刻到位。

    本实验的第1步和第4步都是靠鼠标模拟点击来实现的,那两个按钮都不是标准控件,我们无法靠发送消息触发它们。

    //获得窗口的屏幕坐标加上"+300"按钮的相对位置,可得需要点击的位置
    int scrX = _V3.WinGetPosX(_WinTitle) + 650;
    int scrY = _V3.WinGetPosY(_WinTitle) + 380;
    
    //立刻移动到(scrX,scrY)处, 点击鼠标左键一次
    _V3.MouseClick("LEFT", scrX, scrY, 1,0);
    

    再来看看,键盘输入是如何模拟的,直接上例子:

    //首先需要让光标移动到需要输入的地方
    _V3.MouseClick("LEFT", scrX, scrY, 1);
    
    //如果输入的地方是标准控件,还可直接使用ControlFocus达到目的
     _V3.ControlFocus(_WinTitle, "", "[CLASS:TNoPasteEdit; INSTANCE:2]");
    
    //用Send函数发送字符
    //^a 表示 Ctrl+a组合键,全选TextBox的内容
    // {DEL} 按下删除键
    //80000 输入80000
    _V3.Send("^a{DEL}80000");
    

    操控标准控件

    AutoItX中以Control*开头的函数多是关于标准控件的,所谓标准控件,也就是那些可以用AutoIt Window Info工具捕捉到的控件。
    下面看个例子,实验第2步出价文本框的设置以及第3步“自动查询公开信息”CheckBox操作:

    //Step 2. 读取出价TextBox中的内容, ControlGetText 的参数值都是通过AutoIt Window Info工具抓取的
    string pricestr = _V3.ControlGetText(_WinTitle, "", "[CLASS:TNoPasteEdit; INSTANCE:2]");
    
    int price = 0;
    if (Int32.TryParse(pricestr, out price))
    {
    	//出价+600后,写入出价TextBox中
    	_V3.ControlSetText(_WinTitle, "", "[CLASS:TNoPasteEdit; INSTANCE:2]", (price + 600).ToString());
    }
    
    //Step 3. Uncheck “自动查询公开信息” 复选框
    _V3.ControlCommand(_WinTitle,"","[CLASS:TCheckBox; INSTANCE:1]","UnCheck","");
    

    操控窗口

    在自动界面操作中,常需要判断窗口的状态,来决定下一步的动作。如,在实验第4步中点击出价按钮之后,我们需要知道是否成功打开验证码窗口,然后才能提取验证码进行识别。

    //等待验证码窗口激活,最长等待10秒 即timeout = 10s
    //验证码窗口的Title和主窗口相同,为了区别这里使用了窗口的[CLASS:]
    	
    if (0 != _V3.WinWaitActive("[CLASS:TImageCodeForm]", "", 10))
    {
    	//判断状态 验证码窗口是否可见
       	if ((_V3.WinGetState("[CLASS:TImageCodeForm]", "") & 2) == 2)
       	{
       		MessageBox.Show("验证码窗口打开了");
    		//TODO: 抓取、识别验证码
      	}
    }
    

    结束语

    最后提醒一下,发布您的程序时,如果目标机上没有安装AutoIt,您需要运行regsvr32 AutoItX3.dll注册一下组件(需要管理员权限,AutoItX3.dll 在安装目录下找)。

    好了,希望您能喜欢AutoItX组件,继续探索它的功能,开发一些有趣的应用。

    附件:

    SimuAutoIt.zip 本文例子程序

  • 相关阅读:
    Scala中有关时间的转换操作
    Scala基础
    IDEA 从github拉取代码与推送代码
    IDEA把项目推送到github
    Flink on yarn-session启动出错 Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.yarn.exceptions.YarnException org.apache.hadoop.conf.Configuration
    spark sql导出数据到mysql 出现BLOB类型
    编译Kafka0.11版本遇到的坑!!! 日志无法打印og4j:WARN No appenders could be found for logger(kafka.$Kafka.)
    C#
    js得到分页栏
    js获取浏览器地址栏传递的参数
  • 原文地址:https://www.cnblogs.com/shenwx/p/5394427.html
Copyright © 2020-2023  润新知