zoukankan      html  css  js  c++  java
  • SerialPort实现对串口COM的操作(有些纠结)

         这段时间做了一个小型贷款软件,包括客户管理,交易管理,存折管理和打印,统计分析等模块,其中要求结合存折读卡器一起使用,比如添加存折的时候,存折号要求刷完卡后读出来,刷卡后可以显示客户信息等,和银行的刷卡机差不多。

         客户买的刷卡机器提前没给我说一声,商家没有提供动态库,接口之类的,所以只能自己写一个对串口操作的,一般对CoM操作的程序要么用js写,要么就是写一个ActiveX组建,因为主要是对本机的串口操作的,所以保证读卡程序在客户端执行,这两个是很好的选择,这里我用的是后者,用C#写了一个ActiveX组件,在实现的过程中也遇到了很多问题,刚开始自己写了一个C/S结构的,可以正常读取,可是B/S确出了一些问题

    我才用了微软提供的SerialPort类,大概的流程是这样的:

    首先,找到计算机中可用的COM名称,代码如下

      foreach (string com in System.IO.Ports.SerialPort.GetPortNames())
                {
                     //获取可用的串号    
                if (serialPort1.IsOpen)
                    {
                        serialPort1.Close();
                    }
                    //若串口可以打开说明可以用,否则继续查找可用的串口
                    if (serialPort1.IsOpen)
                    {
                        serialPort1.PortName = com;
                        break;
                    }
                }

    其次,设置串口的参数,包括波特率,协议,数据长度等,代码如下

       serialPort1.BaudRate = 9600;

                serialPort1.Parity = 0;

                serialPort1.DataBits = 8;

    然后,打开串口,发送命令,,这个时候设备的灯会亮,等待你的刷卡

     if (!serialPort1.IsOpen)
                {
                    serialPort1.Open();
                }
                byte[] data = new byte[2];
                data[0] = 0x1b;
                data[1] = 0x5d;
                serialPort1.Write(data, 02);

    再次,调用SerialPortDataReceived事件执行刷卡后的动作,比如刷完卡后就让卡号独到页面的文本框中,这里面需要ActiceX去调用页面的JavaScript

    serialPort1.DataReceived+=new System.IO.Ports.SerialDataReceivedEventHandler(serialPort1_DataReceived);
      void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                try
                {
                    Thread.Sleep(50);/
                    int bytes = serialPort1.BytesToRead;
                
                    byte[] buffer = new byte[bytes];
              
                    serialPort1.Read(buffer, 0, bytes);
                    string strbuffer = Encoding.ASCII.GetString(buffer);
                    string romovestartChar = strbuffer.Substring(2);
                    string rightInfo = romovestartChar.Substring(0, romovestartChar.IndexOf('?'));
                    temphtml.execScript(functionstr + "('" + rightInfo + "')""JScript");   
                    if (serialPort1.IsOpen)
                    {
                        serialPort1.Close();
                    }
                }
                catch (Exception ex)
                {
                    if (serialPort1.IsOpen)
                    {
                        serialPort1.Close();
                    }
                    MessageBox.Show(ex.Message);
                }
            }

    其中, temphtml.execScript(functionstr + "('" + rightInfo + "')", "JScript");   就是调用页面的js函数的,这里简答的说一下关于ActiveX是如何调用Js

    首先,我们要加入micsoft.mshtml引用

    using mshtml;

     

            private IHTMLWindow2 temphtml = null;

            private string functionstr = "";

     

            public void RegJs(object win, string fuc)

            {

                temphtml = (IHTMLWindow2)win;

                if (temphtml != null && !string.IsNullOrEmpty(fuc))

                {

                    functionstr = fuc;

                }

                else

                {

                    temphtml = null;

                    functionstr = "";

                    MessageBox.Show("注册脚本失败");

                }

            }

    加载页面的时候,页面就调用RegJs完成传值,把窗体和js函数传到activeX

     <script type="text/javascript">

            window.onload = function () {

                document.getElementById("Object1").RegJs(window, "Show"); //将页面对象,和所需调用的js方法名传给activex

    }  

    //activex调用的js方法,将卡号转到页面的文本框中

     function Show(str) {

                document.getElementById("text1").value = str;

            }

     

    然后在ActiveX就可以调用temphtml.execScript(functionstr + "('" + rightInfo + "')", "JScript");就可以完成调用赋值了

     

    接着上面的说说,自己也用按钮测试了,当点击按钮的时候确实可以把值传过去,也就是说,只要在ActiveX触发事件,都可以实现传值,但是问题就出现在这里了,当我触发刷卡事件serialPort1.DataReceived的时候(这个事件却是可以触发,测试过了),就是传不过去卡号,而且还报有异常和错误:指定的转化无效,很是郁闷,也咨询了高手,自己也查了资料,就是不知道是什么原因,在这里,希望知道原因的朋友给予指导,谢谢了

    没办法,就换了一个方式,完成了

    打开页面的时候,打开串口,初始化串口参数,发送命令,然后开始刷卡,刷卡完成后,本来想放个按钮获得卡号的,可是感觉客户操作起来可能不太方便,就用键盘代替,按下回车键获取卡号,按下空格键重启设备,总的来说,这样也可以,只是没有立刷立获数据的效果完美吧,等以后有时间在研究其他的办法去解决….

     

    代码下载:

         Demo源码下载

  • 相关阅读:
    amfphp1.9 class mapping初探
    C#程序打包.exe应用程序
    数据库备份方案
    ListView 控件使用
    在C#中运用SQLDMO备份和恢复Microsoft SQL Server数据库
    .NET
    转载:MATLAB 符号函数作图
    整理雷达相关
    Python 程序 运行过程
    struts2 文件上传显示进度条
  • 原文地址:https://www.cnblogs.com/shuang121/p/2532660.html
Copyright © 2011-2022 走看看