SerialPort IOException Workaround in C#

2023-05-16

ref : http://zachsaw.blogspot.com/2010/07/serialport-ioexception-workaround-in-c.html

As promised, I've whipped up a quick workaround to fix the problem as described here.

Here's the code:

 


  1 using System;
  2 using System.IO;
  3 using System.IO.Ports;
  4 using System.Runtime.InteropServices;
  5 using System.Text;
  6 using Microsoft.Win32.SafeHandles;
  7 
  8 namespace SerialPortTester
  9 {
 10     public class SerialPortFixer : IDisposable
 11     {
 12         public static void Execute(string portName)
 13         {
 14             using (new SerialPortFixer(portName))
 15             {
 16             }
 17         }
 18         #region IDisposable Members
 19 
 20         public void Dispose()
 21         {
 22             if (m_Handle != null)
 23             {
 24                 m_Handle.Close();
 25                 m_Handle = null;
 26             }
 27         }
 28 
 29         #endregion
 30 
 31         #region Implementation
 32 
 33         private const int DcbFlagAbortOnError = 14;
 34         private const int CommStateRetries = 10;
 35         private SafeFileHandle m_Handle;
 36 
 37         private SerialPortFixer(string portName)
 38         {
 39             const int dwFlagsAndAttributes = 0x40000000;
 40             const int dwAccess = unchecked((int) 0xC0000000); 
 41  
 42             if ((portName == null) || !portName.StartsWith("COM", StringComparison.OrdinalIgnoreCase))
 43             {
 44                 throw new ArgumentException("Invalid Serial Port", "portName");
 45             }
 46             SafeFileHandle hFile = CreateFile(@"\\.\" + portName, dwAccess, 0, IntPtr.Zero, 3, dwFlagsAndAttributes,
 47                                               IntPtr.Zero);
 48             if (hFile.IsInvalid)
 49             {
 50                 WinIoError();
 51             }
 52             try
 53             {
 54                 int fileType = GetFileType(hFile);
 55                 if ((fileType != 2) && (fileType != 0))
 56                 {
 57                      throw new ArgumentException("Invalid Serial Port", "portName");
 58                 }
 59                 m_Handle = hFile;
 60                 InitializeDcb();
 61             }
 62             catch
 63             {
 64                 hFile.Close();
 65                 m_Handle = null;
 66                 throw;
 67             }
 68         }
 69 
 70         [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 71         private static extern int FormatMessage(int dwFlags, HandleRef lpSource, int dwMessageId, int dwLanguageId,
 72                                                 StringBuilder lpBuffer, int nSize, IntPtr arguments);
 73 
 74         [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 75         private static extern bool GetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
 76 
 77         [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 78         private static extern bool SetCommState(SafeFileHandle hFile, ref Dcb lpDcb);
 79 
 80         [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 81         private static extern bool ClearCommError(SafeFileHandle hFile, ref int lpErrors, ref Comstat lpStat);
 82 
 83         [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
 84         private static extern SafeFileHandle CreateFile(string lpFileName, int dwDesiredAccess, int dwShareMode,
 85                                                         IntPtr securityAttrs, int dwCreationDisposition,
 86                                                         int dwFlagsAndAttributes, IntPtr hTemplateFile);
 87 
 88         [DllImport("kernel32.dll", SetLastError = true)]
 89         private static extern int GetFileType(SafeFileHandle hFile);
 90 
 91         private void InitializeDcb()
 92         {
 93             Dcb dcb = new Dcb();
 94             GetCommStateNative(ref dcb);
 95             dcb.Flags &= ~(1u << DcbFlagAbortOnError);
 96             SetCommStateNative(ref dcb);
 97         }
 98 
 99         private static string GetMessage(int errorCode)
100         {
101             StringBuilder lpBuffer = new StringBuilder(0x200);
102             if (
103                 FormatMessage(0x3200, new HandleRef(null, IntPtr.Zero), errorCode, 0, lpBuffer, lpBuffer.Capacity,
104                               IntPtr.Zero) != 0)
105             {
106                 return lpBuffer.ToString();
107             }
108             return "Unknown Error";
109         }
110 
111         private static int MakeHrFromErrorCode(int errorCode)
112         {
113             return (int) (0x80070000 | (uint) errorCode);
114         }
115 
116         private static void WinIoError()
117         {
118             int errorCode = Marshal.GetLastWin32Error();
119             throw new IOException(GetMessage(errorCode), MakeHrFromErrorCode(errorCode));
120         }
121 
122         private void GetCommStateNative(ref Dcb lpDcb)
123         {
124             int commErrors = 0;
125             Comstat comStat = new Comstat();
126 
127             for (int i = 0; i < CommStateRetries; i++)
128             {
129                 if (!ClearCommError(m_Handle, ref commErrors, ref comStat))
130                 {
131                      WinIoError();
132                 }
133                 if (GetCommState(m_Handle, ref lpDcb))
134                 {
135                      break;
136                 }
137                 if (i == CommStateRetries - 1)
138                 {
139                      WinIoError();
140                 }
141             }
142         } 
143  
144         private void SetCommStateNative(ref Dcb lpDcb)
145         {
146             int commErrors = 0;
147             Comstat comStat = new Comstat(); 
148  
149             for (int i = 0; i < CommStateRetries; i++)
150             {
151                  if (!ClearCommError(m_Handle, ref commErrors, ref comStat))
152                  {
153                      WinIoError();
154                  }
155                  if (SetCommState(m_Handle, ref lpDcb))
156                  {
157                      break;
158                  }
159                  if (i == CommStateRetries - 1)
160                  {
161                      WinIoError();
162                  }
163             }
164         }
165 
166         #region Nested type: COMSTAT
167 
168         [StructLayout(LayoutKind.Sequential)]
169         private struct Comstat
170         {
171             public readonly uint Flags;
172             public readonly uint cbInQue;
173             public readonly uint cbOutQue;
174         }
175 
176         #endregion
177 
178         #region Nested type: DCB
179 
180         [StructLayout(LayoutKind.Sequential)]
181         private struct Dcb
182         {
183             public readonly uint DCBlength;
184             public readonly uint BaudRate;
185             public uint Flags;
186             public readonly ushort wReserved;
187             public readonly ushort XonLim;
188             public readonly ushort XoffLim;
189             public readonly byte ByteSize;
190             public readonly byte Parity;
191             public readonly byte StopBits;
192             public readonly byte XonChar;
193             public readonly byte XoffChar;
194             public readonly byte ErrorChar;
195             public readonly byte EofChar;
196             public readonly byte EvtChar;
197             public readonly ushort wReserved1;
198         }
199 
200         #endregion
201 
202         #endregion
203     }
204 
205     internal class Program
206     {
207         private static void Main(string[] args)
208         {
209             SerialPortFixer.Execute("COM1");
210             using (SerialPort port = new SerialPort("COM1"))
211             {
212                 port.Write("test");
213             }
214         }
215     }
216 }   

 

 

 

转载于:https://www.cnblogs.com/binsys/articles/2513129.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SerialPort IOException Workaround in C# 的相关文章

  • Python自动选择串口(适用于Arduino)

    目前 Python 程序必须知道设备 Arduino 位于哪个端口 然后 Python 才能与设备进行通信 Problem 每当设备拔出并重新插入时 其 COM 端口都会发生变化 因此必须再次向 Python 提供正确的串行端口 以便它找到
  • STM32 上的 ADC 单次转换

    我正在研究 STM32 F103x 上的 ADC 编程 并从最简单的情况 单次转换开始 测量内部温度传感器 连接到 ADC1 的值 并使用 USART 将其发送到 COM 端口 目标似乎很明确 但是当我尝试将源代码下载到闪存时 它不会向 C
  • 推荐一款便宜的串口设备

    我需要将我编写的 Java 应用程序与使用串行端口进行通信的医疗设备集成 该设备相当昂贵 而且也不那么便携 我希望能够随时随地测试代码 但在需要插入串行设备并开始测试之前 您只能做这么多 因此 我正在寻找一种使用串行端口进行通信的廉价便携式
  • C#:使用 Winforms 关闭 SerialPort 的正确方法

    我有一个应用程序 我可以从串行端口读取数据 一切正常 直到我关闭该应用程序 当我单击 X 时 应用程序只是挂起 UI 无响应 我从 DataReceived 事件处理程序中的端口读取数据 并在 FormClosed 发生时关闭端口 priv
  • 适用于嵌入式设备的良好串行通信协议/堆栈? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 在为各种项目编写了几个不同的自定义串行协议后 我开始对每次重新发明轮子感到沮丧 我一直在寻找更通用的解
  • 非重叠串行端口挂在 CloseHandle 处

    我编写了一个自己开发的串行端口类 为了简单起见 我使用了阻塞 同步 不重叠 我浏览了所有 MSDN 文档 这对我来说很困难 我在从端口打开 传输或接收字节方面没有任何问题 所有操作都是同步并且不存在线程复杂性 function TSeria
  • 使用 Qt 打开 SOCAT 创建的虚拟串口

    我正在 MacOS 上开发 Qt5 应用程序 我想测试我的应用程序串行端口通信 我想用socat http www dest unreach org socat 但我无法打开使用 socat 创建的端口 QSerialPortInfo av
  • 在c#中通过设备名称获取蓝牙设备的COM端口

    我用 C 编写一些代码来获取映射具有特定名称的蓝牙设备的 COM 端口 我尝试了几种与列出的类似的解决方案here https stackoverflow com questions 25908734 get name of bluetoo
  • 如何检测属于 gsm/3g-modem 的 tty 是数据端口还是控制端口?

    我目前正在为 Linux 路由器编写一个小工具 当我将适当的调制解调器插入其 USB 端口时 该工具会建立 wwan gsm 3g 连接 当设备插入时 会注册多个 tty 我当前维护一个制造商和设备的列表 以及它们注册的 tty 中的哪个是
  • 读取串行数据而不需要高 CPU 使用率

    我想在 Linux 下用简单的 C 或 C 程序读取通过 FTDI 串行 接口从 Arduino 发送的消息 Arduino 发送两个字符的 标头 一个命令字节 后跟几个字节的数据 具体取决于命令 我的第一次尝试是简单地使用 open 和
  • 只是想从 Java Applet 将数据写入串行端口?

    几天来我一直在抓狂地想弄清楚为什么这似乎永远不起作用 首先 这是我的配置 Windows 7 x64JDK 7 x86JRE 7 x86火狐 x86由 Thin 提供服务的 Rails 3Java 设置使得 下一代插件 不处于活动状态 但它
  • 无法在 Ubuntu 上的 PyCharm 上启动终端

    我想运行一段代码 为此 我在我的 Ubuntu 机器上安装了 PyCharm 现在 当我打开 PyCharm 应用程序并尝试打开终端时 它会抛出错误并且不会打开终端 java io IOException Exec tty错误 未知的pyc
  • Lucene 上打开的文件太多错误

    我正在进行的项目是对一定数量的数据 长文本 建立索引 并将它们与每个时间间隔 大约 15 到 30 分钟 的单词列表进行比较 一段时间后 比如说第 35 轮 在开始索引第 36 轮的新数据集时 发生了此错误 ERROR 2011 06 01
  • Linux 上共享串口

    我正在使用 Raspberry Pi 进行一个项目 该项目需要能够写入和读取串行端口 但来自不同的程序 程序 A 需要能够从外围设备 A 正在发送数据的串行端口读取数据 程序B需要向串口写入数据 外设B正在监听串口 供参考 本例中程序A是G
  • 如何用 C 语言从串行(SPI)连接读取数据?

    我正在尝试编写一个程序 该程序将安装在 Linux MCU Raspberry Pi 上 该程序将读取从另一个 MCU 我将自己构建的自制程序 发送到它的串行数据 我研究了如何做到这一点 并认为我有 大局 但仍然缺少一些东西 其一 我需要启
  • 二进制串口读取c中丢失的字节

    我正在将二进制数据从 arduino 发送到运行此代码的串行端口 在十六进制模式下使用cutecom可以清楚地读取我对该串行端口的期望 如下所示 00000000 24 04 85 ab 47 43 04 04 24 04 85 ab 47
  • Node.js |如何通过串口向设备发送和接收一个字节?

    我正在尝试编写使用以下方法的 Node js 脚本serialport https serialport io 用于读取和写入数据的 npm 包COM5串行端口 使用 RS 232 电缆连接到设备 该设备会自动传输其拥有的数据 要检索设备内
  • qt 读取就绪信号

    我正在尝试与运行 1996 年处理器的设备建立串行连接 这意味着数据传输回我可能需要几秒钟的时间 我知道readyRead每次有新数据可用时都会生成信号 但我的问题是生成多长时间 这也是我可以测试就绪读取是否较低的一种方法 因为如果当它们不
  • 计算串行通信的块校验字符 (BCC)

    我通过 NET 的 SerialPort 类通过串行与设备进行通信 并且根据第三方设备规范要求 我需要计算 块检查字符 我被告知的唯一信息是 这是一个异或运算 XOR 并且必须对所有角色执行 那么 如果我有字符串 Bob 001 将如何计算
  • 串行 I/O 与 Windows/Windows CE 重叠/不重叠

    抱歉 这不是一个大问题 但更多的是帮助那些在这些特定问题上遇到问题的人 我正在解决的问题需要使用串行 I O 但主要在 Windows CE 6 0 下运行 然而 最近有人问我该应用程序是否也可以在 Windows 下运行 所以我开始着手解

随机推荐