C# 串口模拟键盘输入

      最近遇到一个需求:需要在网站的文本输入栏上输入条码和回车; 查了一下资料,记录如下:

     最后的方案: 两台电脑用串口连接,从A机器发送信息到串口, B机器从串口读到信息,并模拟键盘输出。 

  

[csharp] view plain copy
 
  1. public class CKeyController  
  2.    {  
  3.        [System.Runtime.InteropServices.DllImport("user32")]  
  4.        static extern void keybd_event(  
  5.            byte bVk,  
  6.            byte bScan,  
  7.            uint dwFlags,  
  8.            uint dwExtraInfo  
  9.            );  
  10.        const uint KEYEVENTF_EXTENDEDKEY = 0x1;  
  11.        const uint KEYEVENTF_KEYUP = 0x2;  
  12.        private static Dictionary<string, byte> keycode = new Dictionary<string, byte>();  
  13.   
  14.        [DllImport("user32.dll")]  
  15.        public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);  
  16.        [DllImport("User32.DLL")]  
  17.        public static extern int SendMessage(IntPtr hWnd,uint Msg, int wParam, string lParam);  
  18.        [DllImport("User32.DLL")]  
  19.        public static extern int SendMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);  
  20.   
  21.        [DllImport("User32.DLL")]  
  22.        public static extern IntPtr FindWindowEx(IntPtr hwndParent,  
  23.            IntPtr hwndChildAfter, string lpszClass, string lpszWindow);  
  24.        public const uint WM_SETTEXT = 0x000C;  
  25.        public const uint WM_CHAR = 0x0102;  
  26.        public static int WM_KEYDOWN = 0x0100;  
  27.        //释放一个键  
  28.        public static int WM_KEYUP = 0x0101;  
  29.   
  30.        public void InitKey()  
  31.        {  
  32.            keycode = new Dictionary<string, byte>();  
  33.            keycode.Add("A", 65);  
  34.            keycode.Add("B", 66);  
  35.            keycode.Add("C", 67);  
  36.            keycode.Add("D", 68);  
  37.            keycode.Add("E", 69);  
  38.            keycode.Add("F", 70);  
  39.            keycode.Add("G", 71);  
  40.            keycode.Add("H", 72);  
  41.            keycode.Add("I", 73);  
  42.            keycode.Add("J", 74);  
  43.            keycode.Add("K", 75);  
  44.            keycode.Add("L", 76);  
  45.            keycode.Add("M", 77);  
  46.            keycode.Add("N", 78);  
  47.            keycode.Add("O", 79);  
  48.            keycode.Add("P", 80);  
  49.            keycode.Add("Q", 81);  
  50.            keycode.Add("R", 82);  
  51.            keycode.Add("S", 83);  
  52.            keycode.Add("T", 84);  
  53.            keycode.Add("U", 85);  
  54.            keycode.Add("V", 86);  
  55.            keycode.Add("W", 87);  
  56.            keycode.Add("X", 88);  
  57.            keycode.Add("Y", 89);  
  58.            keycode.Add("Z", 90);  
  59.            keycode.Add("0", 48);  
  60.            keycode.Add("1", 49);  
  61.            keycode.Add("2", 50);  
  62.            keycode.Add("3", 51);  
  63.            keycode.Add("4", 52);  
  64.            keycode.Add("5", 53);  
  65.            keycode.Add("6", 54);  
  66.            keycode.Add("7", 55);  
  67.            keycode.Add("8", 56);  
  68.            keycode.Add("9", 57);  
  69.            keycode.Add(".", 0x6E);  
  70.            keycode.Add("LEFT", 0x25);  
  71.            keycode.Add("UP", 0x26);  
  72.            keycode.Add("RIGHT", 0x27);  
  73.            keycode.Add("DOWN", 0x28);  
  74.            keycode.Add("-", 0x6D);  
  75.            keycode.Add("{ENTER}", 13);  
  76.        }  
  77.   
  78.        public static void KeyBoardDo(string key)  
  79.        {  
  80.            keybd_event(keycode[key], 0x45, KEYEVENTF_EXTENDEDKEY | 0, 0);  
  81.            keybd_event(keycode[key], 0x45, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);  
  82.        }  
  83.   
  84.        /// <summary>  
  85.        /// 使用keybd_event发送。 缺点是不能指定接受的窗口名称;接受窗口必须为当前活动窗口。  
  86.        /// </summary>  
  87.        /// <param name="barcode"></param>  
  88.        public void SendBarcode(string barcode)  
  89.        {  
  90.            for (int k = 0; k < barcode.Length; k++)  
  91.            {  
  92.                string ak = barcode.Substring(k, 1);  
  93.                KeyBoardDo(ak);  
  94.            }  
  95.            KeyBoardDo("{ENTER}");  
  96.        }  
  97.   
  98.   
  99.        /// <summary>  
  100.        ///   
  101.        /// </summary>  
  102.        /// <param name="barcode"></param>  
  103.        public void SendKeys(string barcode)  
  104.        {  
  105.            System.Windows.Forms.SendKeys.Send(barcode);  
  106.            System.Windows.Forms.SendKeys.Send("{ENTER}");  
  107.        }  
  108.   
  109.   
  110.        /// <summary>  
  111.        ///可以指定窗口,并且窗口可以为不活动状态; 即应用程序不在显示器最上层。  
  112.        /// </summary>  
  113.        /// <param name="hello"></param>  
  114.        public void SendKeyByMessage(string hello)  
  115.        {  
  116.            System.Diagnostics.Process[] GamesProcess = System.Diagnostics.Process.GetProcessesByName("notepad");  
  117.            if (GamesProcess.Length == 0) return;  
  118.   
  119.            IntPtr hWnd = FindWindowEx(GamesProcess[0].MainWindowHandle,  
  120.            IntPtr.Zero, "Edit", null);             
  121.   
  122.            //SendMessage(hWnd, WM_SETTEXT, 0, hello); //清空记事本中内容;写入字符;并且光标回到第一行第一个位置。  
  123.            int key = 0;  
  124.            for (int k = 0; k < hello.Length; k++)  
  125.            {  
  126.                string ak = hello.Substring(k, 1);  
  127.                key = keycode[ak];  
  128.                SendMessage(hWnd, WM_CHAR, key, 0);  
  129.            }  
  130.   
  131.            key = keycode["{ENTER}"];  
  132.            SendMessage(hWnd, WM_CHAR, key, 0);      //往记事本中添加内容。       
  133.        }  
  134.   
  135.    }  



  类中有3中将字符串输出的功能:

1. 

[csharp] view plain copy
 
  1. keybd_event: 不能指定输出对象  
[csharp] view plain copy
 
  1. 2. <pre name="code" class="csharp"><pre name="code" class="csharp">SendMessage(hWnd, WM_CHAR, key, 0);   
[csharp] view plain copy
 
  1. 输出一个字符到指定的窗口。  
[csharp] view plain copy
 
  1. <pre name="code" class="csharp">SendMessage(hWnd, WM_SETTEXT, 0, hello);  
[csharp] view plain copy
 
  1. 清空记事本中内容;写入字符;并且光标回到第一行第一个位置。   


[csharp] view plain copy
 
  1. 3. <pre name="code" class="csharp">SendKeys  
[csharp] view plain copy
 
  1. 这个一直没有实验成功,一直会有软件不响应;除非使用手动激活其他窗口。 具体原因没有细查。  
[csharp] view plain copy
 
  1.   
[csharp] view plain copy
 
  1. 串口控制代码  
[csharp] view plain copy
 
  1. <pre name="code" class="csharp"> public class CComController  
  2.     {  
  3.         private SerialPort sp = null;  
  4.   
  5.         /// <summary>  
  6.         /// 打开串口  
  7.         /// </summary>  
  8.         /// <param name="protName">串口号</param>  
  9.         /// <param name="baudRate">波特率</param>  
  10.         /// <param name="dataBit">数据位</param>  
  11.         /// <param name="stopBits">停止位</param>  
  12.         /// /// <param name="parity">校验位</param>  
  13.         /// <returns></returns>  
  14.         public bool OpenCom(string protName, int baudRate, int dataBit, float stopBits, int parity)  
  15.         {  
  16.             bool flag = true;  
  17.             if (sp == null)  
  18.             {  
  19.                 sp = new SerialPort();  
  20.             }  
  21.             sp.PortName = protName;//串口号  
  22.             sp.BaudRate = baudRate;//波特率  
  23.             sp.ReadTimeout = 10;  
  24.             float f = stopBits;//停止位  
  25.             if (f == 0)  
  26.             {  
  27.                 sp.StopBits = StopBits.None;  
  28.             }  
  29.             else if (f == 1.5)  
  30.             {  
  31.                 sp.StopBits = StopBits.OnePointFive;  
  32.             }  
  33.             else if (f == 1)  
  34.             {  
  35.                 sp.StopBits = StopBits.One;  
  36.             }  
  37.             else  
  38.             {  
  39.                 sp.StopBits = StopBits.Two;  
  40.             }  
  41.   
  42.             sp.DataBits = dataBit;//数据位  
  43.   
  44.             if (parity == 0)  
  45.             {  
  46.                 sp.Parity = Parity.None;  
  47.             }  
  48.             else if (parity == 1)  
  49.             {  
  50.                 sp.Parity = Parity.Odd;  
  51.             }  
  52.             else if (parity == 2)  
  53.             {  
  54.                 sp.Parity = Parity.Even;  
  55.             }  
  56.             else  
  57.             {  
  58.                 sp.Parity = Parity.None;  
  59.             }  
  60.              
  61.             try  
  62.             {  
  63.                 if (!sp.IsOpen)  
  64.                 {  
  65.                     sp.Open();  
  66.                 }  
  67.             }  
  68.             catch (Exception)  
  69.             {  
  70.                 flag = false;  
  71.             }  
  72.             return flag;  
  73.         }  
  74.   
  75.         /// <summary>  
  76.         /// 关闭端口  
  77.         /// </summary>  
  78.         /// <returns></returns>  
  79.         public bool CloseCom()  
  80.         {  
  81.             try  
  82.             {  
  83.                 if (sp.IsOpen)  
  84.                 {  
  85.                     sp.Close();  
  86.                 }  
  87.                 return true;  
  88.             }  
  89.             catch  
  90.             {  
  91.                 return false;  
  92.             }  
  93.         }  
  94.   
  95.         public string ReadLine()  
  96.         {  
  97.             try  
  98.             {  
  99.                 string receive = sp.ReadLine();  
  100.                 return receive;  
  101.             }  
  102.             catch (Exception ex)  
  103.             {  
  104.                 return "";  
  105.             }  
  106.         }  
  107.   
  108.         public bool WriteLine(string barcode)  
  109.         {  
  110.             sp.WriteLine(barcode);  
  111.             return true;  
  112.         }  
  113.     }  




[csharp] view plain copy
 
  1. 客户端代码:  
[csharp] view plain copy
 
  1.  public partial class Form1 : Form  
  2.     {  
  3.         CComController com;  
  4.         public Form1()  
  5.         {  
  6.             InitializeComponent();  
  7.   
  8.   
  9.   
  10.   
  11.             com = new CComController();  
  12.             com.OpenCom("COM1", 115200, 8, 1, 0);  
  13.         }  
  14.   
  15.   
  16.         public void SendBarcode()  
  17.         {  
  18.   
  19.   
  20.               
  21.         }  
  22.   
  23.   
  24.         private void btnSend_Click(object sender, EventArgs e)  
  25.         {             
  26.             string barcode = txtBarcode.Text;  
  27.             com.WriteLine(barcode);  
  28.         }  
  29.     }  
[csharp] view plain copy
 
  1.   
[csharp] view plain copy
 
  1. 服务端:  
[csharp] view plain copy
 
  1. namespace ComServer  
  2. {  
  3.     public partial class Form1 : Form  
  4.     {  
  5.         CComController comController;  
  6.         CKeyController keyController;  
  7.         public Form1()  
  8.         {  
  9.             InitializeComponent();  
  10.             //textBox1.Focus();  
  11.   
  12.   
  13.             comController = new CComController();  
  14.             comController.OpenCom("COM1", 115200, 8, 1, 0);  
  15.               
  16.             keyController = new CKeyController();  
  17.             keyController.InitKey();  
  18.             Thread readThread = new Thread(new ThreadStart(ThreadReadBarcode));  
  19.             readThread.Start();  
  20.         }  
  21.   
  22.   
  23.         public void ThreadReadBarcode()  
  24.         {  
  25.             while (true)  
  26.             {  
  27.                 string barcode = comController.ReadLine();  
  28.                 if (barcode != "" && barcode != null)  
  29.                 {                      
  30.                     keyController.SendKeyByMessage(barcode);                      
  31.                 }  
  32.   
  33.   
  34.                 Thread.Sleep(200);  
  35.             }  
  36.         }  
  37.     }  
  38. }  
[csharp] view plain copy
 
  1.   
[csharp] view plain copy
 
  1.   
[csharp] view plain copy
 



原文地址:https://www.cnblogs.com/weiterli/p/7846889.html