internal static extern bool SetCommState(IntPtr hFile, [In] ref Dcb lpDCB);
public static IntPtr OpenPort(int portNum, RS232Config config) { // Validate inputs if (portNum < 0 || portNum > 255) { throw new ArgumentException("Invalid port number (valid range is [0, 255]).", nameof(portNum)); } if (!config.IsValid(out var msg)) { throw new ArgumentException(msg, nameof(config)); } // Open the port var fileName = "\\\\.\\COM" + portNum; var hPort = RS232PInvoke.CreateFileA( fileName, // File name for com port FileAccess.ReadWrite, // Read/Write access for (rx/tx) FileShare.None, // no share IntPtr.Zero, // no security FileMode.Open, // open existing FileAttributes.Normal, // normal file IntPtr.Zero); // no template file if (hPort.ToInt32() == -1) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } // Configure the port var dcb = new Dcb { BaudRate = (uint)config.BaudRate, ByteSize = (byte)config.DataBits, Parity = config.Parity, StopBits = config.StopBits, }; if (!RS232PInvoke.SetCommState(hPort, ref dcb)) { RS232PInvoke.CloseHandle(hPort); throw new Exception("Could not configure COM port settings."); } // Configure the port time-outs var timeouts = new COMMTIMEOUTS { // Read operations return immediately ReadIntervalTimeout = 0xFFFF_FFFF, // MAXDWORD ReadTotalTimeoutMultiplier = 0, ReadTotalTimeoutConstant = 0, // Timeouts not used for write operations WriteTotalTimeoutMultiplier = 0, WriteTotalTimeoutConstant = 0, }; if (!RS232PInvoke.SetCommTimeouts(hPort, ref timeouts)) { RS232PInvoke.CloseHandle(hPort); throw new Exception("Could not configure COM port timeouts."); } // Return port handle for caller return(hPort); }