asp.net – 与Silverlight 5的串行通信(COM端口)
发布时间:2020-12-16 03:58:17 所属栏目:asp.Net 来源:网络整理
导读:我正在ASP.NET网站上工作,我需要从客户端访问USB设备. 我已经看到Silverlight 5,通过使用P / Invoke,允许我们访问客户端机器上的dll.我计划在我的一个页面中添加一个silverlight控件,它将与我的USB设备进行交互.这样,使用这种设备的每个客户,只需要在我的网
我正在ASP.NET网站上工作,我需要从客户端访问USB设备.
我已经看到Silverlight 5,通过使用P / Invoke,允许我们访问客户端机器上的dll.我计划在我的一个页面中添加一个silverlight控件,它将与我的USB设备进行交互.这样,使用这种设备的每个客户,只需要在我的网站上连接并开始使用它. 尽管如此,作为与USB设备进行这种交互的初学者,我该如何设法做到这一点? 哪个windows dll会为我提供一个与usb设备交互的好方法? 进一步的信息: >我需要能够通过COM端口进行通信.典型的串行通信.我该如何设法做到这一点? 出于测试目的,我可以通过像“Hercules”这样的应用程序连接到我的设备,我基本上需要在我的silverlight模块中重新编写这种连接…… 你们有什么例子吗? 谢谢你的帮助, 解决方法
我找到了一个包装类,它使我能够在Silverlight 5中创建与串行端口的连接.我现在可以通过串行通信访问我的USB设备.
由于我花了很多时间努力使其发挥作用,我将与您分享这个课程: using System; using System.IO; using System.Runtime.InteropServices; using System.Text; namespace TestSerialDLL { public class SerialWrapper : IDisposable { #region Enum public enum StopBits { None,One,Two,OnePointFive,} public enum Parity { None,Odd,Even,Mark,Space,} #endregion #region Fields /// <summary> /// The baud rate at which the communications device operates. /// </summary> private readonly int iBaudRate; /// <summary> /// The number of bits in the bytes to be transmitted and received. /// </summary> private readonly byte byteSize; /// <summary> /// The system handle to the serial port connection ('file' handle). /// </summary> private IntPtr pHandle = IntPtr.Zero; /// <summary> /// The parity scheme to be used. /// </summary> private readonly Parity parity; /// <summary> /// The name of the serial port to connect to. /// </summary> private readonly string sPortName; /// <summary> /// The number of bits in the bytes to be transmitted and received. /// </summary> private readonly StopBits stopBits; #endregion #region Constructor /// <summary> /// Creates a new instance of SerialCom. /// </summary> /// <param>The name of the serial port to connect to</param> /// <param>The baud rate at which the communications device operates</param> /// <param>The number of stop bits to be used</param> /// <param>The parity scheme to be used</param> /// <param>The number of bits in the bytes to be transmitted and received</param> public SerialWrapper(string portName,int baudRate,StopBits stopBits,Parity parity,byte byteSize) { if (stopBits == StopBits.None) throw new ArgumentException("stopBits cannot be StopBits.None","stopBits"); if (byteSize < 5 || byteSize > 8) throw new ArgumentOutOfRangeException("The number of data bits must be 5 to 8 bits.","byteSize"); if (baudRate < 110 || baudRate > 256000) throw new ArgumentOutOfRangeException("Invalid baud rate specified.","baudRate"); if ((byteSize == 5 && stopBits == StopBits.Two) || (stopBits == StopBits.OnePointFive && byteSize > 5)) throw new ArgumentException("The use of 5 data bits with 2 stop bits is an invalid combination," + "as is 6,7,or 8 data bits with 1.5 stop bits."); this.sPortName = portName; this.iBaudRate = baudRate; this.byteSize = byteSize; this.stopBits = stopBits; this.parity = parity; } /// <summary> /// Creates a new instance of SerialCom. /// </summary> /// <param>The name of the serial port to connect to</param> /// <param>The baud rate at which the communications device operates</param> /// <param>The number of stop bits to be used</param> /// <param>The parity scheme to be used</param> public SerialWrapper(string portName,Parity parity) : this(portName,baudRate,stopBits,parity,8) { } #endregion #region Open /// <summary> /// Opens and initializes the serial connection. /// </summary> /// <returns>Whether or not the operation succeeded</returns> public bool Open() { pHandle = CreateFile(this.sPortName,FileAccess.ReadWrite,FileShare.None,IntPtr.Zero,FileMode.Open,IntPtr.Zero); if (pHandle == IntPtr.Zero) return false; if (ConfigureSerialPort()) return true; else { Dispose(); return false; } } #endregion #region Write /// <summary> /// Transmits the specified array of bytes. /// </summary> /// <param>The bytes to write</param> /// <returns>The number of bytes written (-1 if error)</returns> public int Write(byte[] data) { FailIfNotConnected(); if (data == null) return 0; int bytesWritten; if (WriteFile(pHandle,data,data.Length,out bytesWritten,0)) return bytesWritten; return -1; } /// <summary> /// Transmits the specified string. /// </summary> /// <param>The string to write</param> /// <returns>The number of bytes written (-1 if error)</returns> public int Write(string data) { FailIfNotConnected(); // convert the string to bytes byte[] bytes; if (data == null) { bytes = null; } else { bytes = Encoding.UTF8.GetBytes(data); } return Write(bytes); } /// <summary> /// Transmits the specified string and appends the carriage return to the end /// if it does not exist. /// </summary> /// <remarks> /// Note that the string must end in 'rn' before any serial device will interpret the data /// sent. For ease of programmability,this method should be used instead of Write() when you /// want to automatically execute the specified command string. /// </remarks> /// <param>The string to write</param> /// <returns>The number of bytes written (-1 if error)</returns> public int WriteLine(string data) { if (data != null && !data.EndsWith("rn")) data += "rn"; return Write(data); } #endregion #region Read /// <summary> /// Reads any bytes that have been received and writes them to the specified array. /// </summary> /// <param>The array to write the read data to</param> /// <returns>The number of bytes read (-1 if error)</returns> public int Read(byte[] data) { FailIfNotConnected(); if (data == null) return 0; int bytesRead; if (ReadFile(pHandle,out bytesRead,0)) return bytesRead; return -1; } /// <summary> /// Reads any data that has been received as a string. /// </summary> /// <param>The maximum number of bytes to read</param> /// <returns>The data received (null if no data)</returns> public string ReadString(int maxBytesToRead) { if (maxBytesToRead < 1) throw new ArgumentOutOfRangeException("maxBytesToRead"); byte[] bytes = new byte[maxBytesToRead]; int numBytes = Read(bytes); //string data = ASCIIEncoding.ASCII.GetString(bytes,numBytes); string data = Encoding.UTF8.GetString(bytes,numBytes); return data; } #endregion #region Dispose Utils /// <summary> /// Disconnects and disposes of the SerialCom instance. /// </summary> public void Dispose() { if (pHandle != IntPtr.Zero) { CloseHandle(pHandle); pHandle = IntPtr.Zero; } } /// <summary> /// Flushes the serial I/O buffers. /// </summary> /// <returns>Whether or not the operation succeeded</returns> public bool Flush() { FailIfNotConnected(); const int PURGE_RXCLEAR = 0x0008; // input buffer const int PURGE_TXCLEAR = 0x0004; // output buffer return PurgeComm(pHandle,PURGE_RXCLEAR | PURGE_TXCLEAR); } #endregion #region Private Helpers /// <summary> /// Configures the serial device based on the connection parameters pased in by the user. /// </summary> /// <returns>Whether or not the operation succeeded</returns> private bool ConfigureSerialPort() { DCB serialConfig = new DCB(); if (GetCommState(pHandle,ref serialConfig)) { // setup the DCB struct with the serial settings we need serialConfig.BaudRate = (uint)this.iBaudRate; serialConfig.ByteSize = this.byteSize; serialConfig.fBinary = 1; // must be true serialConfig.fDtrControl = 1; // DTR_CONTROL_ENABLE "Enables the DTR line when the device is opened and leaves it on." serialConfig.fAbortOnError = 0; // false serialConfig.fTXContinueOnXoff = 0; // false serialConfig.fParity = 1; // true so that the Parity member is looked at switch (this.parity) { case Parity.Even: serialConfig.Parity = 2; break; case Parity.Mark: serialConfig.Parity = 3; break; case Parity.Odd: serialConfig.Parity = 1; break; case Parity.Space: serialConfig.Parity = 4; break; case Parity.None: default: serialConfig.Parity = 0; break; } switch (this.stopBits) { case StopBits.One: serialConfig.StopBits = 0; break; case StopBits.OnePointFive: serialConfig.StopBits = 1; break; case StopBits.Two: serialConfig.StopBits = 2; break; case StopBits.None: default: throw new ArgumentException("stopBits cannot be StopBits.None"); } if (SetCommState(pHandle,ref serialConfig)) { // set the serial connection timeouts COMMTIMEOUTS timeouts = new COMMTIMEOUTS(); timeouts.ReadIntervalTimeout = 1; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.ReadTotalTimeoutConstant = 0; timeouts.WriteTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 0; if (SetCommTimeouts(pHandle,ref timeouts)) { return true; } else { return false; } } else { return false; } } else { return false; } } /// <summary> /// Helper that throws a InvalidOperationException if we don't have a serial connection. /// </summary> private void FailIfNotConnected() { if (pHandle == IntPtr.Zero) throw new InvalidOperationException("You must be connected to the serial port before performing this operation."); } #endregion #region Native Helpers #region Native structures /// <summary> /// Contains the time-out parameters for a communications device. /// </summary> [StructLayout(LayoutKind.Sequential)] struct COMMTIMEOUTS { public uint ReadIntervalTimeout; public uint ReadTotalTimeoutMultiplier; public uint ReadTotalTimeoutConstant; public uint WriteTotalTimeoutMultiplier; public uint WriteTotalTimeoutConstant; } /// <summary> /// Defines the control setting for a serial communications device. /// </summary> [StructLayout(LayoutKind.Sequential)] struct DCB { public int DCBlength; public uint BaudRate; public uint Flags; public ushort wReserved; public ushort XonLim; public ushort XoffLim; public byte ByteSize; public byte Parity; public byte StopBits; public sbyte XonChar; public sbyte XoffChar; public sbyte ErrorChar; public sbyte EofChar; public sbyte EvtChar; public ushort wReserved1; public uint fBinary; public uint fParity; public uint fOutxCtsFlow; public uint fOutxDsrFlow; public uint fDtrControl; public uint fDsrSensitivity; public uint fTXContinueOnXoff; public uint fOutX; public uint fInX; public uint fErrorChar; public uint fNull; public uint fRtsControl; public uint fAbortOnError; } #endregion #region Native Methods // Used to get a handle to the serial port so that we can read/write to it. [DllImport("kernel32.dll",SetLastError = true,CharSet = CharSet.Auto)] static extern IntPtr CreateFile(string fileName,[MarshalAs(UnmanagedType.U4)] FileAccess fileAccess,[MarshalAs(UnmanagedType.U4)] FileShare fileShare,IntPtr securityAttributes,[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,int flags,IntPtr template); // Used to close the handle to the serial port. [DllImport("kernel32.dll",SetLastError = true)] static extern bool CloseHandle(IntPtr hObject); // Used to get the state of the serial port so that we can configure it. [DllImport("kernel32.dll")] static extern bool GetCommState(IntPtr hFile,ref DCB lpDCB); // Used to configure the serial port. [DllImport("kernel32.dll")] static extern bool SetCommState(IntPtr hFile,[In] ref DCB lpDCB); // Used to set the connection timeouts on our serial connection. [DllImport("kernel32.dll",SetLastError = true)] static extern bool SetCommTimeouts(IntPtr hFile,ref COMMTIMEOUTS lpCommTimeouts); // Used to read bytes from the serial connection. [DllImport("kernel32.dll")] static extern bool ReadFile(IntPtr hFile,byte[] lpBuffer,int nNumberOfBytesToRead,out int lpNumberOfBytesRead,int lpOverlapped); // Used to write bytes to the serial connection. [DllImport("kernel32.dll",SetLastError = true)] static extern bool WriteFile(IntPtr hFile,int nNumberOfBytesToWrite,out int lpNumberOfBytesWritten,int lpOverlapped); // Used to flush the I/O buffers. [DllImport("kernel32.dll",SetLastError = true)] static extern bool PurgeComm(IntPtr hFile,int dwFlags); #endregion #endregion } } 以下是SerialWrapper的示例: using (var p = new SerialWrapper(@".COM12",9600,SerialWrapper.StopBits.One,SerialWrapper.Parity.None)) { if (!p.Open()) { Console.WriteLine("Unable to connect."); return; } while (true) { Console.Write(p.ReadString(1024)); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- asp.net – 带有MVC 2的自定义ViewModel强类型HTML Helper在
- asp.net – 基于web.config的url重写的绝对最小内容是什么?
- asp.net-mvc – 如何将IoC成员资格提供程序与ASP.NET MVC集
- asp.net – 仅为Web服务关闭customErrors
- asp.net DropDownList的’EnableViewState = false’
- asp.net-mvc – 谁设置HttpContext.User.Identity的IsAuthe
- asp.net-mvc – 通过使用EF 4.1 DBContext为SaveChanges分配
- 适用于ASP.NET的SaaS入门套件,涵盖订阅,计费等
- 从ASP.NET页面获取请求变量
- asp.net-mvc – 从客户端检测到潜在危险的Request.Form值
推荐文章
站长推荐
- efcore 新特性 SaveChanges Events
- asp.net-mvc – 通过使用EF 4.1 DBContext为Save
- asp.net-mvc-4 – 在MVC4中捕获404错误
- asp.net – 我想要一个Master UserControl(一个M
- ASP.NET:隐藏gridview中的列
- asp.net – 是否可以在.net中读取.eml文件
- 单元测试ASP.NET WebAPI控制器的POST操作
- asp.net-mvc – MultiSelect jqgrid MVC3的OnCli
- asp.net-web-api – 从OWIN中间件更改响应对象
- .net – 实体框架遇到的最大池大小4.3
热点阅读