[轉]WEB頁獲取串列埠資料
阿新 • • 發佈:2018-11-23
本文轉自:https://www.cnblogs.com/rockyhm/p/3434200.html
最近做一個B/S的專案,需要讀取電子秤的值,之前一直沒做過,也沒有經驗,於是在網上找到很多 大致分兩種
- 使用ActiveX控制元件,JS呼叫MSCOMM32.dll的串列埠控制元件對串列埠進行控制
- 使用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控制元件(吉日老師提醒)最後嵌入網頁中讀取資料 如下:
- 第一步:新建專案,如下圖,選擇windows下的類庫專案。
- 在專案中新增一個類:IObjectSafety.cs
- 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); } }
- 新增一個使用者控制元件 MyActiveXControl.cs
- 修改 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控制元件進行測試
- 新增響應的事件程式碼如下
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); } } } }
- 至此讀取串列埠資料的Active控制元件製作完畢 下面我們來製作一個安裝包,新建一個安裝專案
- 在安裝專案的檔案系統中新增剛才之前我們製作的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 開始監聽