1. 程式人生 > >[轉]WEB頁獲取串列埠資料

[轉]WEB頁獲取串列埠資料

本文轉自:https://www.cnblogs.com/rockyhm/p/3434200.html

最近做一個B/S的專案,需要讀取電子秤的值,之前一直沒做過,也沒有經驗,於是在網上找到很多  大致分兩種

  1. 使用ActiveX控制元件,JS呼叫MSCOMM32.dll的串列埠控制元件對串列埠進行控制
  2. 使用C#語言的控制元件對串列埠進行控制,然後使用JS+AJAX與C#進行互動獲得串列埠資料

詳情見  使用JS獲得串列埠資料 http://blog.csdn.net/xuing/article/details/6688306    但是小弟用這兩種辦法都獲取到資料

串列埠配置如下:

1                  serialPort1.PortName = "COM1";          //埠名稱
2             serialPort1.BaudRate = 1200;            //波特率
3             serialPort1.Parity = Parity.None;       //奇偶效驗
4             serialPort1.StopBits = StopBits.One;    //效驗
5             serialPort1.DataBits = 8;               //每個位元組的資料位長度

 

最後換種思路:使用C#寫一個ActiveX控制元件(吉日老師提醒)最後嵌入網頁中讀取資料   如下:

  1. 第一步:新建專案,如下圖,選擇windows下的類庫專案。
  2. 在專案中新增一個類:IObjectSafety.cs 
  3. IObjectSafety.cs程式碼如下: 複製程式碼
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.InteropServices;
    namespace MyActive
    {
        //Guid唯一,不可變更,否則將無法通過IE瀏覽器的ActiveX控制元件的安全認證  
        [ComImport, Guid("CB5BDC81-93C1-11CF-8F20-00805F2CD064")]
        [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IObjectSafety
        {
            [PreserveSig]
            void GetInterfacceSafyOptions(int riid,out int pdwSupportedOptions,out int pdwEnabledOptions);
        }
    }
    複製程式碼

     

  4. 新增一個使用者控制元件 MyActiveXControl.cs 
  5. 修改 MyActiveXControl.cs 程式碼,讓其繼承IObjectSafety,定義相應的Guid,該Guid就是ActiveX的classid  複製程式碼
    using System;
     using System.Collections.Generic;
     using System.ComponentModel;
     using System.Drawing;
     using System.Data;
     using System.Text;
     using System.Windows.Forms;
     using System.Runtime.InteropServices;
    
    namespace MyActiveX
     {
         [Guid("218849AF-1B2C-457B-ACD5-B42AC8D17EB7"), ComVisible(true)]
         public partial class MyActiveXControl : UserControl,IObjectSafety
         {
             public MyActiveXControl()
             {
                 InitializeComponent();
             }
    
            #region IObjectSafety 成員 用於ActiveX控制元件安全信任
            public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
             {
                 pdwSupportedOptions = 1;
                 pdwEnabledOptions = 2;
             }
    
            public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
             {
                 throw new NotImplementedException();
             }
             #endregion
         }
     }
    複製程式碼

    至此   Active控制元件製作完畢      下面我們新增文字框、按鈕、SerialPort、Timer控制元件進行測試                                     

  6. 新增響應的事件程式碼如下 複製程式碼
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Drawing;
    using System.Data;
    using System.IO.Ports;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    using MyActive;
    
    namespace MyActiveX
    {
        //不可改變
        [Guid("218849AF-1B2C-457B-ACD5-B42AC8D17EB7"), ComVisible(true)]
        public partial class MyActiveXControl : UserControl, IObjectSafety
        {
            
            public MyActiveXControl()
            {
                InitializeComponent();
            }
    
            public delegate void HandleInterfaceUpdataDelegate(string text);//定義一個委託
                         
            private HandleInterfaceUpdataDelegate interfaceUpdataHandle;//宣告
    
            bool isClose = false;//是否關閉
    
            #region IObjectSafety 成員 用於ActiveX控制元件安全信任
            public void GetInterfacceSafyOptions(int riid, out int pdwSupportedOptions, out int pdwEnabledOptions)
            {
                pdwSupportedOptions = 1;
                pdwEnabledOptions = 2;
            }
    
            public void SetInterfaceSafetyOptions(int riid, int dwOptionsSetMask, int dwEnabledOptions)
            {
                throw new NotImplementedException();
            }
            #endregion
            
            
            private void button1_Click(object sender, EventArgs e)
            {
                try
                {
                    interfaceUpdataHandle = new HandleInterfaceUpdataDelegate(UpdateTextBox);//例項化委託物件 
    
                    serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);
                    if (!serialPort1.IsOpen)
                    {
                        serialPort1.Open();
                    }
                    button2.Enabled = true;
                    button1.Enabled=false;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    return;
                }
                timer1.Enabled = true;
                
            }
            /// <summary>
            /// 控制元件載入事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void MyActiveXControl_Load(object sender, EventArgs e)
            {
                setOrgComb();
            }
            /// <summary>
            /// 初始化串列埠
            /// </summary>
            private void setOrgComb()
            {
                serialPort1.PortName = "COM1";          //埠名稱
                serialPort1.BaudRate = 1200;            //波特率
                serialPort1.Parity = Parity.None;       //奇偶效驗
                serialPort1.StopBits = StopBits.One;    //效驗
                serialPort1.DataBits = 8;               //每個位元組的資料位長度
            }
            /// <summary>
            /// 更新資料
            /// </summary>
            /// <param name="text"></param>
            private void UpdateTextBox(string text)
            {
                //richTextBox1.Text = text + "\n\t" + richTextBox1.Text;
                richTextBox1.Text = text;
            }
    
            /// <summary>
            /// 接收資料是發生
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
            {
                //獲取接收緩衝區中資料的位元組數
                if (serialPort1.BytesToRead > 5)
                {
    
                    string strTemp = serialPort1.ReadExisting();//讀取串列埠
                    double weight = -1;//獲取到的重量
                    foreach (string str in strTemp.Split('='))//獲取穩定的值
                    {
                        double flog = 0;
                        //資料是否正常
                        if(double.TryParse(str, out flog)&&str.IndexOf('.')>0&&str[str.Length-1]!='.')
                        {
                            //資料轉換   串列埠獲取到的資料是倒敘的  因此進行反轉
                            char[] charArray = str.ToCharArray();
                            Array.Reverse(charArray);
                            string left = new string(charArray).Split('.')[0];
                            string right = new string(charArray).Split('.')[1];
                            if (right.Length==2)
                            {
                                weight = int.Parse(left) + int.Parse(right) / 100.0;
                            }
                        }
                    }
                    if(weight>=0)
                    {
                        //在擁有控制元件的基礎視窗控制代碼的執行緒上,用指定的引數列表執行指定委託。                    
                        this.Invoke(interfaceUpdataHandle, weight.ToString());//取到資料   更新
                    }
                }
            }
    
            private void button2_Click(object sender, EventArgs e)
            {
                try
                {
                    button1.Enabled = true;
                    button2.Enabled = false;
                    serialPort1.Close();
                    timer1.Enabled = false;
                   
                    
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
    
            private void timer1_Tick(object sender, EventArgs e)
            {
                if (isClose)
                {
                    return;
                }
                try
                {
                    string send = "" + (char)(27) + 'p';
                    send = serialPort1.ReadExisting();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                    button2_Click(null, null);
                }
            }
        }
    }
    複製程式碼


     

  7. 至此讀取串列埠資料的Active控制元件製作完畢   下面我們來製作一個安裝包,新建一個安裝專案
  8. 在安裝專案的檔案系統中新增剛才之前我們製作的ActiveX的DLL:MyActiveX.dll
    (特別注意:在檔案新增進來後,右擊檔案選擇屬性,設定其屬性Register值為:vsdraCOM)

 

    9.    生成安裝程式,在專案MyActiveX\Setup1\Debug下找到Setup1.msi,雙擊安裝它。
         然後在該目錄下新建一個html檔案(test.html)用於測試我們的ActiceX控制元件。HTML程式碼如下:

複製程式碼
<html>
 <title>Powered by yyzq.net Email:[email protected]</title>
 <head>
 </head>
 <body>
 <div>
 <object id="yyzq" classid="clsid:218849AF-1B2C-457B-ACD5-B42AC8D17EB7"
         width="320"
         height="240"
         codebase="Setup1.msi">
 </object>
 </div>
 </body>
 </html>
複製程式碼

在IE瀏覽器下開啟test.html,點選start     開始監聽