|
using RichCreator.Utility.Structs;
|
using System;
|
using System.Collections.Generic;
|
using System.Diagnostics;
|
using System.IO.Ports;
|
using System.Text;
|
using System.Threading;
|
|
namespace RichCreator.Utility.InputControl
|
{
|
/// <summary>
|
/// 硬件键盘控制
|
/// </summary>
|
public class HardwareInputControl : IInputControl, IDisposable
|
{
|
private SerialPortConnect connect;
|
private bool isfinalize = false;
|
|
private Int32 receiveCounter = 0;//接收计数
|
|
private byte[] mouseBuffer = new byte[5];//鼠标移动缓存
|
private byte[] keyBuffer = new byte[9];//键盘输入缓存
|
|
private Dictionary<char, HIDMapContainer> CharHIDMap = new Dictionary<char, HIDMapContainer>() {
|
{'~',new HIDMapContainer(HIDCode.HeavyNote,true)},
|
{'!',new HIDMapContainer(HIDCode.Num1,true)},
|
{'@',new HIDMapContainer(HIDCode.Num2,true)},
|
{'#',new HIDMapContainer(HIDCode.Num3,true)},
|
{'$',new HIDMapContainer(HIDCode.Num4,true)},
|
{'%',new HIDMapContainer(HIDCode.Num5,true)},
|
{'^',new HIDMapContainer(HIDCode.Num6,true)},
|
{'&',new HIDMapContainer(HIDCode.Num7,true)},
|
{'*',new HIDMapContainer(HIDCode.Num8,true)},
|
{'(',new HIDMapContainer(HIDCode.Num9,true)},
|
{')',new HIDMapContainer(HIDCode.Num0,true)},
|
{'_',new HIDMapContainer(HIDCode.Minus,true)},
|
{'+',new HIDMapContainer(HIDCode.Equal,true)},
|
{'`',new HIDMapContainer(HIDCode.HeavyNote,false)},
|
{'1',new HIDMapContainer(HIDCode.Num1,false)},
|
{'2',new HIDMapContainer(HIDCode.Num2,false)},
|
{'3',new HIDMapContainer(HIDCode.Num3,false)},
|
{'4',new HIDMapContainer(HIDCode.Num4,false)},
|
{'5',new HIDMapContainer(HIDCode.Num5,false)},
|
{'6',new HIDMapContainer(HIDCode.Num6,false)},
|
{'7',new HIDMapContainer(HIDCode.Num7,false)},
|
{'8',new HIDMapContainer(HIDCode.Num8,false)},
|
{'9',new HIDMapContainer(HIDCode.Num9,false)},
|
{'0',new HIDMapContainer(HIDCode.Num0,false)},
|
{'-',new HIDMapContainer(HIDCode.Minus,false)},
|
{'=',new HIDMapContainer(HIDCode.Equal,false)},
|
{'a',new HIDMapContainer(HIDCode.A,false)},
|
{'b',new HIDMapContainer(HIDCode.B,false)},
|
{'c',new HIDMapContainer(HIDCode.C,false)},
|
{'d',new HIDMapContainer(HIDCode.D,false)},
|
{'e',new HIDMapContainer(HIDCode.E,false)},
|
{'f',new HIDMapContainer(HIDCode.F,false)},
|
{'g',new HIDMapContainer(HIDCode.G,false)},
|
{'h',new HIDMapContainer(HIDCode.H,false)},
|
{'i',new HIDMapContainer(HIDCode.I,false)},
|
{'j',new HIDMapContainer(HIDCode.J,false)},
|
{'k',new HIDMapContainer(HIDCode.K,false)},
|
{'l',new HIDMapContainer(HIDCode.L,false)},
|
{'m',new HIDMapContainer(HIDCode.M,false)},
|
{'n',new HIDMapContainer(HIDCode.N,false)},
|
{'o',new HIDMapContainer(HIDCode.O,false)},
|
{'p',new HIDMapContainer(HIDCode.P,false)},
|
{'q',new HIDMapContainer(HIDCode.Q,false)},
|
{'r',new HIDMapContainer(HIDCode.R,false)},
|
{'s',new HIDMapContainer(HIDCode.S,false)},
|
{'t',new HIDMapContainer(HIDCode.T,false)},
|
{'u',new HIDMapContainer(HIDCode.U,false)},
|
{'v',new HIDMapContainer(HIDCode.V,false)},
|
{'w',new HIDMapContainer(HIDCode.W,false)},
|
{'x',new HIDMapContainer(HIDCode.X,false)},
|
{'y',new HIDMapContainer(HIDCode.Y,false)},
|
{'z',new HIDMapContainer(HIDCode.Z,false)},
|
{'A',new HIDMapContainer(HIDCode.A,true)},
|
{'B',new HIDMapContainer(HIDCode.B,true)},
|
{'C',new HIDMapContainer(HIDCode.C,true)},
|
{'D',new HIDMapContainer(HIDCode.D,true)},
|
{'E',new HIDMapContainer(HIDCode.E,true)},
|
{'F',new HIDMapContainer(HIDCode.F,true)},
|
{'G',new HIDMapContainer(HIDCode.G,true)},
|
{'H',new HIDMapContainer(HIDCode.H,true)},
|
{'I',new HIDMapContainer(HIDCode.I,true)},
|
{'J',new HIDMapContainer(HIDCode.J,true)},
|
{'K',new HIDMapContainer(HIDCode.K,true)},
|
{'L',new HIDMapContainer(HIDCode.L,true)},
|
{'M',new HIDMapContainer(HIDCode.M,true)},
|
{'N',new HIDMapContainer(HIDCode.N,true)},
|
{'O',new HIDMapContainer(HIDCode.O,true)},
|
{'P',new HIDMapContainer(HIDCode.P,true)},
|
{'Q',new HIDMapContainer(HIDCode.Q,true)},
|
{'R',new HIDMapContainer(HIDCode.R,true)},
|
{'S',new HIDMapContainer(HIDCode.S,true)},
|
{'T',new HIDMapContainer(HIDCode.T,true)},
|
{'U',new HIDMapContainer(HIDCode.U,true)},
|
{'V',new HIDMapContainer(HIDCode.V,true)},
|
{'W',new HIDMapContainer(HIDCode.W,true)},
|
{'X',new HIDMapContainer(HIDCode.X,true)},
|
{'Y',new HIDMapContainer(HIDCode.Y,true)},
|
{'Z',new HIDMapContainer(HIDCode.Z,true)},
|
{'[',new HIDMapContainer(HIDCode.LeftSquarebrackets,false)},
|
{']',new HIDMapContainer(HIDCode.RightSquarebrackets,false)},
|
{'\\',new HIDMapContainer(HIDCode.Backslash,false)},
|
{';',new HIDMapContainer(HIDCode.Semicolon,false)},
|
{'\'',new HIDMapContainer(HIDCode.SingleQuotation,false)},
|
{',',new HIDMapContainer(HIDCode.Comma,false)},
|
{'.',new HIDMapContainer(HIDCode.FullStop,false)},
|
{'/',new HIDMapContainer(HIDCode.Slash,false)},
|
{'{',new HIDMapContainer(HIDCode.LeftSquarebrackets,true)},
|
{'}',new HIDMapContainer(HIDCode.RightSquarebrackets,true)},
|
{'|',new HIDMapContainer(HIDCode.Backslash,true)},
|
{':',new HIDMapContainer(HIDCode.Semicolon,true)},
|
{'"',new HIDMapContainer(HIDCode.SingleQuotation,true)},
|
{'<',new HIDMapContainer(HIDCode.Comma,true)},
|
{'>',new HIDMapContainer(HIDCode.FullStop,true)},
|
{'?',new HIDMapContainer(HIDCode.Slash,true)}
|
};
|
|
|
public HardwareInputControl()
|
{
|
string comName = GetComName();
|
if (string.IsNullOrEmpty(comName))
|
{
|
throw new Exception("没有发现键盘硬件");
|
}
|
|
connect = new SerialPortConnect(comName);
|
if (!connect.Connect())
|
{
|
throw new Exception("硬件连接失败");
|
}
|
|
}
|
|
private string ToHexString(byte[] buffer)
|
{
|
StringBuilder builder = new StringBuilder();
|
for (Int32 i = 0; i < buffer.Length; i++)
|
{
|
builder.Append(buffer[i].ToString("X2")).Append(" ");
|
}
|
|
builder.Append("\r\n");
|
return builder.ToString();
|
}
|
|
#region 鼠标
|
public void LikePersonMove(int offsetX, int offsetY, bool leftButtonIsDown, bool midButtonIsDown, bool rightButtonIsDown)
|
{
|
throw new NotImplementedException();
|
}
|
|
public void LikePersonMoveTo(int x, int y, bool leftButtonIsDown, bool midButtonIsDown, bool rightButtonIsDown)
|
{
|
throw new NotImplementedException();
|
}
|
|
/// <summary>
|
/// 移动指定偏移
|
/// </summary>
|
/// <param name="offsetX"></param>
|
/// <param name="offsetY"></param>
|
/// <param name="leftButtonIsDown"></param>
|
/// <param name="midButtonIsDown"></param>
|
/// <param name="rightButtonIsDown"></param>
|
public void Move(int offsetX, int offsetY, bool leftButtonIsDown, bool midButtonIsDown, bool rightButtonIsDown)
|
{
|
Move(offsetX, offsetY, leftButtonIsDown, midButtonIsDown, rightButtonIsDown, false);
|
}
|
|
/// <summary>
|
/// 移动指定偏移
|
/// </summary>
|
/// <param name="offsetX"></param>
|
/// <param name="offsetY"></param>
|
/// <param name="leftButtonIsDown"></param>
|
/// <param name="midButtonIsDown"></param>
|
/// <param name="rightButtonIsDown"></param>
|
/// <param name="likePerson"></param>
|
public void Move(int offsetX, int offsetY, bool leftButtonIsDown, bool midButtonIsDown, bool rightButtonIsDown,bool likePerson)
|
{
|
byte keystatus = 0x00;
|
if (leftButtonIsDown)
|
{
|
keystatus |= 0x01;
|
}
|
if (midButtonIsDown)
|
{
|
keystatus |= 0x04;
|
}
|
|
if (rightButtonIsDown)
|
{
|
keystatus |= 0x02;
|
}
|
|
|
|
byte xmove = 0;
|
byte ymove = 0;
|
|
Int32 offsetXSign = Math.Sign(offsetX);
|
Int32 offsetYSign = Math.Sign(offsetY);
|
offsetX = Math.Abs(offsetX);
|
offsetY = Math.Abs(offsetY);
|
while (true)
|
{
|
xmove = (byte)Math.Min(RandomUtils.MouseMoveDistance, offsetX);
|
ymove = (byte)Math.Min(RandomUtils.MouseMoveDistance, offsetY);
|
|
mouseBuffer[0] = 0x01;
|
mouseBuffer[1] = keystatus;
|
mouseBuffer[2] = (byte)(offsetXSign * xmove);
|
mouseBuffer[3] = (byte)(offsetYSign * ymove);
|
mouseBuffer[4] = 0x00;
|
offsetX -= xmove;
|
offsetY -= ymove;
|
|
this.connect.Send(mouseBuffer, 5);
|
if (offsetX <= 0 && offsetY <= 0)
|
{
|
break;
|
}
|
Int32 pause = RandomUtils.MouseMoveDuration;
|
Thread.Sleep(pause);
|
}
|
}
|
|
/// <summary>
|
/// 移动到指定位置
|
/// </summary>
|
/// <param name="x"></param>
|
/// <param name="y"></param>
|
/// <param name="leftButtonIsDown"></param>
|
/// <param name="midButtonIsDown"></param>
|
/// <param name="rightButtonIsDown"></param>
|
public void MoveTo(int x, int y, bool leftButtonIsDown, bool midButtonIsDown, bool rightButtonIsDown)
|
{
|
Utils.MarshalPoint point = new Utils.MarshalPoint();//必须用与之相兼容的结构体,类也可以
|
Utils.GetCursorPos(ref point);//获取当前鼠标坐标
|
Int32 offsetX = x - point.X;
|
Int32 offsetY = y - point.Y;
|
Move(offsetX, offsetY, leftButtonIsDown, midButtonIsDown, rightButtonIsDown,true);
|
}
|
|
|
/// <summary>
|
/// 鼠标移动指定位置并单击
|
/// </summary>
|
/// <param name="point"></param>
|
public void MoveToAndClick(ZTPoint point)
|
{
|
MoveTo(point.X, point.Y, false, false, false);
|
Thread.Sleep(RandomUtils.G(500,800));
|
Move(0, 0, true, false, false);
|
Thread.Sleep(RandomUtils.MouseClickDuration);
|
Move(0, 0, false, false, false);
|
Thread.Sleep(RandomUtils.MouseClickDuration);
|
}
|
|
|
/// <summary>
|
/// 鼠标移动指定位置并双击
|
/// </summary>
|
/// <param name="point"></param>
|
public void MoveToAndDClick(ZTPoint point)
|
{
|
MoveTo(point.X, point.Y, false, false, false);
|
Thread.Sleep(RandomUtils.G(500, 800));
|
|
Move(0, 0, true, false, false);
|
Thread.Sleep(RandomUtils.MouseClickDuration);
|
Move(0, 0, false, false, false);
|
Thread.Sleep(RandomUtils.MouseClickDuration);
|
|
Move(0, 0, true, false, false);
|
Thread.Sleep(RandomUtils.MouseClickDuration);
|
Move(0, 0, false, false, false);
|
Thread.Sleep(RandomUtils.MouseClickDuration);
|
}
|
#endregion
|
|
#region 键盘
|
public void InputString(string content)
|
{
|
for (int i = 0; i < content.Length; i++)
|
{
|
InputChar(content[i]);
|
Trace.WriteLine(content[i]);
|
Thread.Sleep(100);
|
}
|
}
|
|
public void InputChar(char chr)
|
{
|
if (this.CharHIDMap.ContainsKey(chr))
|
{
|
Trace.Write(chr + "\r\n");
|
HIDMapContainer c = this.CharHIDMap[chr];
|
PutDown(false, false, c.IsShift, false, false, false, false, false, c.Code);
|
Thread.Sleep(100);
|
PutDown(false, false, false, false, false, false, false, false);
|
}
|
}
|
|
|
|
/// <summary>
|
/// 敲击按键
|
/// </summary>
|
/// <param name="pressLeftControl"></param>
|
/// <param name="pressRightControl"></param>
|
/// <param name="pressLeftShift"></param>
|
/// <param name="pressRightShift"></param>
|
/// <param name="pressLeftAlt"></param>
|
/// <param name="pressRightAlt"></param>
|
/// <param name="pressLeftGUI"></param>
|
/// <param name="pressRightGUI"></param>
|
/// <param name="keys">按下的按键,可小于等于6个</param>
|
public void PressKey(bool pressLeftControl, bool pressRightControl, bool pressLeftShift, bool pressRightShift, bool pressLeftAlt, bool pressRightAlt, bool pressLeftGUI, bool pressRightGUI, params HIDCode[] keys)
|
{
|
PutDown(pressLeftControl, pressRightControl, pressLeftShift, pressRightShift, pressLeftAlt, pressRightAlt, pressLeftGUI, pressRightGUI, keys);
|
Thread.Sleep(RandomUtils.KeyPressDuration);
|
PutDown(false, false, false, false, false, false, false, false);
|
Thread.Sleep(RandomUtils.KeyPressDuration);
|
}
|
|
/// <summary>
|
/// 按指定按键指定毫秒
|
/// </summary>
|
/// <param name="keys"></param>
|
/// <param name="pressMillSecond"></param>
|
public void PressKey(Int32 pressMillSecond, params HIDCode[] keys)
|
{
|
PutDown(false,false,false,false,false,false,false,false, keys);
|
Thread.Sleep(pressMillSecond);
|
PutDown(false, false, false, false, false, false, false, false);
|
}
|
|
/// <summary>
|
/// 连续按键
|
/// </summary>
|
/// <param name="keys"></param>
|
public void PressKeys(params HIDCode[] keys)
|
{
|
for (int i = 0; i < keys.Length; i++)
|
{
|
PutDown(false, false, false, false, false, false, false, false, keys[i]);
|
Thread.Sleep(RandomUtils.KeyPressDuration);
|
PutDown(false, false, false, false, false, false, false, false);
|
Thread.Sleep(RandomUtils.KeyPressDurationMin);
|
}
|
}
|
|
|
/// <summary>
|
/// 按下按键
|
/// </summary>
|
/// <param name="pressLeftControl"></param>
|
/// <param name="pressRightControl"></param>
|
/// <param name="pressLeftShift"></param>
|
/// <param name="pressRightShift"></param>
|
/// <param name="pressLeftAlt"></param>
|
/// <param name="pressRightAlt"></param>
|
/// <param name="pressLeftGUI"></param>
|
/// <param name="pressRightGUI"></param>
|
/// <param name="keys"></param>
|
public void PutDown(bool pressLeftControl, bool pressRightControl, bool pressLeftShift, bool pressRightShift, bool pressLeftAlt, bool pressRightAlt, bool pressLeftGUI, bool pressRightGUI, params HIDCode[] keys)
|
{
|
byte status = 0x00;
|
if (pressLeftControl)
|
{
|
status |= 0x01;
|
}
|
|
if (pressLeftShift)
|
{
|
status |= 0x02;
|
}
|
|
if (pressLeftAlt)
|
{
|
status |= 0x04;
|
}
|
|
if (pressLeftGUI)
|
{
|
status |= 0x08;
|
}
|
|
if (pressRightControl)
|
{
|
status |= 0x10;
|
}
|
|
if (pressRightShift)
|
{
|
status |= 0x20;
|
}
|
|
if (pressRightAlt)
|
{
|
status |= 0x40;
|
}
|
|
if (pressRightGUI)
|
{
|
status |= 0x80;
|
}
|
|
keyBuffer[0] = 0x00;
|
keyBuffer[1] = status;
|
keyBuffer[2] = 0x00;
|
Int32 count = Math.Min(6, keys == null ? 0 : keys.Length);
|
byte kv = 0;
|
for (int i = 0; i < 6; i++)
|
{
|
kv = (i < count) ? (byte)keys[i] : (byte)0x00;
|
keyBuffer[3 + i] = kv;
|
}
|
this.connect.Send(keyBuffer, 9);
|
}
|
#endregion
|
|
|
|
/// <summary>
|
/// 仅发送
|
/// </summary>
|
/// <param name="buffer"></param>
|
/// <param name="len"></param>
|
private void Send(byte[] buffer, Int32 len)
|
{
|
this.connect.Send(buffer, buffer.Length);
|
}
|
|
/// <summary>
|
/// 获取COM口
|
/// </summary>
|
/// <returns></returns>
|
private string GetComName()
|
{
|
bool result = false;
|
string[] comNames = SerialPort.GetPortNames();
|
for (int i = 0; i < comNames.Length; i++)
|
{
|
string comName = comNames[i];
|
using (SerialPortConnect connect = new SerialPortConnect(comName))
|
{
|
using (ManualResetEvent locker = new ManualResetEvent(false))
|
{
|
connect.DataReceiveCallback = (datas) =>
|
{
|
string version = Encoding.ASCII.GetString(datas);
|
if (version.StartsWith("Ver:"))
|
{
|
result = true;
|
}
|
else
|
{
|
result = false;
|
}
|
locker.Set();
|
};
|
connect.Connect();
|
QueryVersion(connect);
|
if (locker.WaitOne(1000)&&result==true)
|
{
|
return comName;
|
}
|
}
|
}
|
result = false;
|
}
|
return string.Empty;
|
}
|
|
|
/// <summary>
|
/// 设置PID,VID
|
/// </summary>
|
/// <param name="pid"></param>
|
/// <param name="vid"></param>
|
public void SetPIDVID(UInt16 pid, UInt16 vid)
|
{
|
|
}
|
|
public void QueryVersion(SerialPortConnect connect)
|
{
|
//Ver:20190127.1
|
byte[] data = new byte[] { 0xfe, 0x01, 0x02, 0x03, 0x04, 0xb4 };
|
connect.Send(data, data.Length);
|
}
|
public void Close()
|
{
|
if (!isfinalize)
|
{
|
this.connect.Disconnect();
|
isfinalize = true;
|
GC.SuppressFinalize(this);
|
}
|
|
}
|
|
public void Dispose()
|
{
|
Close();
|
}
|
|
|
/// <summary>
|
/// 字符和hid对象容器
|
/// </summary>
|
public struct HIDMapContainer
|
{
|
public HIDMapContainer(HIDCode code, bool isshift)
|
{
|
this.Code = code;
|
this.IsShift = isshift;
|
}
|
|
/// <summary>
|
/// 字符码
|
/// </summary>
|
public HIDCode Code;
|
|
/// <summary>
|
/// 是否开启上档键
|
/// </summary>
|
public bool IsShift;
|
}
|
}
|
}
|