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 }