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源碼下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM