Search code examples
.netwindows-10serial-portsysinternals

Serial port blocked by none process


Have an issue managing a SerialPort on Windows 10.

I need to plug in a serial device to the computer, it works properly most of the times, but in certains situations the port stops working, just refuses any new connection even when any process is using it, the device manager shows the port is available (the driver is loaded).

Sometimes the SerialPort is available until I disable the port in the device in Windows DeviceManager, restart the computer and enabling it again. Knowing that I've tried using some Microsoft tools:

  • PnPUtil, creating a double click PowerShell script to disable and enable the device. It didn't worked, I had to unplug and plug in physically the serial device. By definition it works with PlugAndPlay devices.
  • DevCon, It makes a similiar thing as PnPUtil, but it specifies that works with any devices pluged to the computer. I made a similar script but got the same result.
  • Handle, I found out the existence of handles, they're like dependencies linked to a process including a device instance (using driver file). When I get the port unused, I tried searching the handle of the SerialPort ("Device/Serial0"), and none process was using it. it's been detected but blocked in someway.
  • ProcessExplorer, this tool is like TaskManager but gives you a detailed view of each processes, including the handles. I confirmed again, the ports is not being used.

Now I'm thinking about some hardware related problem, the serial port is wired as NullModém, which means that only GND, Tx and Rx are connected. so that way of wiring, can't there be any bussines logic problem under RS232, right?

An option could be a driver incompatibility with the motherboard serial port?

Has someone any other ideas that I could try?

Edit: An under/overvoltage could possibly blocked a serial port?


Solution

  • I kind of solved the problem.

    It turns out that if Windows detects constant data flow when the serial port enumarion starts (system boot or when you enable/load a new devices), Windows identifies the serial port COM as a serial mouse, creating a new devices linked to that serial port. So the port won't be available for any other process.

    I found out the problem reading this refs (including a similar question):

    I'd like to give more details about what I did.

    I made a C# ConsoleApp which constanly sends data to the port by using a USB-RS232 adapter connected to another PC which has a legacy serial port. This is the app's code:

    class SerialPortConnection : IDisposable
    {
        SerialPort _serialPort;
        public void Start()
        {
            _serialPort = new SerialPort();
            _serialPort.BaudRate = 9600;
            _serialPort.Parity = Parity.None;
            _serialPort.StopBits = StopBits.One;
            _serialPort.Handshake = Handshake.None;
            _serialPort.PortName = "COM5";
    
            _serialPort.ReadTimeout = 500;
            _serialPort.WriteTimeout = 100;
    
            this._serialPort.Open();
            int i = 10 * 60 * 1000;//120 segundos
    
            while (i > 0)
            {
                this._serialPort.Write("ZABCDEFGHIJKLNOPQRSTUG");//22 bytes ->22 x 4(250ms) = 88 bytes/s -> con baudrate 9600
                
                
                System.Threading.Thread.Sleep(250);                                            
            
            }
            
        }
        public void Dispose()
        {
            this._serialPort.Close();
        }
    }
    

    I tried several amounts of bytes, at the end I realized that if the app sends exactly or more than 22 bytes each 250ms using 9600 baudrate and force an enumeration ( windows reboot or disabling/enabling or deleting the device), the port gets blocked and Windows creates a new device, a Serial Mouse which takes control of the COM port:

    Screenshot Serial Mouse in Windows Device Manager

    So that's why the port refuses any new connection. To avoid it, you only need to disable the Serial Mouse (not uninstall, because in future reboots, windows may load it again).

    You also can modify the Windows Registry to avoid the service to start:

    \HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\sermouse
    

    Replacing the value 3 to 4 in the key Start. (3 is Default, 4 is Disabled).

    if you don't have acces to Windows Registry, there's a simple (and temporary) solution. Let's recap: the error comes from the identification (enumeration) of the port, when data is coming into the port, so, if you can avoid data flowing at the moment of the enumeration, then you got it.

    1. Unplug the port before turning on the PC, and once Windows starts, you can plug it.

    2. If you can manipulate your Serial device to stop working (actually, stop sending data) like turning it off, or pausing in some way the device, then you can boot Windows and then resume the device work.

    3. If you have acces to Windows device Manager, you can apply the second point by disabling/enabling the COM port rather than rebooting Window.

    4. You also can disable the COM port, unplug it, and enable it again (the SerialMouse will be removed) and plug it.

    Getting these solutions took me more than a week. I hope it could be useful for someone else.