locked
Serialport unplug and plug. RRS feed

  • Question

  • I have a Pharos GPS-360 USB serial GPS.  I would like to unplug the USB connector and then plug it back in and reuse the GPS.  I haven't found a way to do anything with the serial port once the USB is unplugged.  Can't close or dispose the port or reestablish communication with the GPS after replugging.

        public Form1()
        {
          InitializeComponent();
          serialPort1.Open();
        }
        
    private void button1_Click(object sender, EventArgs e)
        {
          serialPort1.Close();
          serialPort1.Open();
        }

    As long as the USB in not unplugged, the button can be clicked without problem.  Unplugging and replugging gives an "The device does not recognize the command." error.  How can I reuse the serial port without closing the application?

    Monday, February 8, 2010 9:26 AM

Answers

  • Actually, the solution is much simpler:

    public Form1()
    {
        InitializeComponent();
        serialPort1.Open();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            serialPort1.Close();
        }
        catch (Exception)
        {
        }
        serialPort1 = new SerialPort(...);
        serialPort1.Open();
    }
    

    First of all you are not supposed to use a disposed object (you're trying to re-open it). That's a no-no for any IDisposable object.

    The reason that SerialPort.Close can throw an exception is that it attempts to perform operations on the port handle (SetCommMask, EscapeCommFunction). These are going to fail on a port handle that has gone away. The good news is that the implementation of SerialPort.Dispose will call CloseHandle on the port handle even if an exception occurs (earlier) in the SerialPort.Dispose method, so the above code should work just fine.

    • Marked as answer by JohnWein Wednesday, February 10, 2010 10:48 PM
    Wednesday, February 10, 2010 9:50 PM

All replies

  • Not sure if it helps, but you need a delay between serialPort1.Close and SerialPort1.Open to allow the background thread to close down properly before you reopen the port. This is a flaw in SerialPort.

    The most efficient way is to block the UI thread temporary (after an Application.DoEvents() statements, which ensures an immediate graphical response) as this leaves more time for the lower priority background thread to close down so that the time can be kept short.

    serialPort1.Close();
    Application.DoEvents();
    Sleep(200);
    serialPort1.Open();

    This is a school example of both the "forbidden" calls used simultaneously, but nobody has ever been able to come up with a method, which gives a better user experience.

    You can find a little more information about this in chapter "SerialPort Events" of my SerialPort tutorial .



    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.
    Monday, February 8, 2010 10:08 AM
  • Not sure if it helps, but you need a delay between serialPort1.Close and SerialPort1.Open to allow the background thread to close down properly before you reopen the port. This is a flaw in SerialPort.


    That doesn't seem to be true in my case when I have a connection.   Once disconnected the port can''t be closed.
    Monday, February 8, 2010 12:42 PM
  • I think you must use WMI (from .Net). I've write an article to cacth 'plug-unplug' of a USB device, so I tyhink it can be nearly useful.
    Also if you don't understand my language (and you don't relay on the 'universal' translator :o)), I think you can understand the code:

    http://www.visual-basic.it/articoli/dcNET_WMI_USB.htm
    please, mark this as answer if it is THE answer
    ----------------
    Diego Cattaruzza
    Microsoft MVP - Visual Basic: Development
    blog: http://community.visual-basic.it/Diego
    web site: http://www.visual-basic.it
    Monday, February 8, 2010 12:59 PM
  • There is a bug, which - at least previously - coursed an UnauthorizedAccessException in the underlying SerialStream when you disconnect a USB-serialPort converter. If you Google a little with these keywords, you will find numerous threads about this bug - for example http://social.msdn.microsoft.com/Forums/en-SG/netfxnetcom/thread/8b02d5d0-b84e-447a-b028-f853d6c6c690 . Microsoft has tried to fix that bug several times (.Net 2.0 SP2), but as far as I know so far without success - see the warning in the first chapter of my tutorial.

    I don't know if there is anything to do about it except for stop using USB-serial converters. It is and has always been a very bad solution - just ask nobugz.


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.
    Monday, February 8, 2010 1:04 PM
  • The problem I have is disposing of the SerialPort.  The arrival and departure of the port is broadcast as a message to WndProc.  When the USB cable is disconnected, I want to dispose the port so that when the cable is reconnected I can reopen the port.  The only way I have been able to reopen the port is to close and restart the application.
    Monday, February 8, 2010 3:05 PM
  • I assume that you don't have any static class members associated with the port instance, and that you unsubscribe to any SerialPort events.



    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, February 8, 2010 3:30 PM
  • I found something that works.  If I place the serial port code in a second form, I can dispose the serial port in the FormClosing event the second time it is executed.  The first time through it throws an error (there is no UI error message, at least not in the IDE) and the form doesn't close.  The second time the form closes normally and I can then reload the form and reconnect the serial port.
    Monday, February 8, 2010 3:41 PM
  • I don't think that the message will help you. The moment you pull the plug, it is "good buy" and you can do nothing about it. It is too late to try to dispose SerialPort when the departure message gets processed by WndProc. The damage has been done and the port cannot close.

    It seems that Microsoft has given up on this. First they told me that they didn't dare to try to fix the bug because they would not risk the system to become unstable !!! In .Net 3.5 they then tried. I don't know if it was this attempt that coursed it, but .Net 3.5 RTM became completely useless for all serialPort applications and nobody knew why or ever found out! In .Net 3.5 SP1, SerialPort seems to work again by some miracle, but the bug is still not fixed and it is obviously a wasp's nest, which nobody dare to touch.

    Long time ago, Justin Van Pattern, who is - or at least were - in charge of this, promised me a collaboration about a modern SerialPort implementation, but nothing happens. I have my own problems with that implementation because Microsoft is so "clever" as to take 11 bits from the Receiver FIFO in the UART, throw the 3 vital status bits away (after firing events) and then stores the result in a 16-bit stream. The result is that the synchronization is lost and cannot be regained so you cannot use any of the modern communication methods like 9th bit communication or telegram separation by means of Break :-(



    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.
    Monday, February 8, 2010 3:55 PM
  • You found something that works! 
    Wrap it up, man. 


        interface ISerialPort
        {
            int BytesToRead
            {
                get;
            }
            void Close();
            void Open();
        }

        class SerialPortWrapper : Form, ISerialPort
        {
            SerialPort port;
            public SerialPortWrapper()
            {
                port = new SerialPort();           
            }
            // expose as many members of SerialPort as you need.
            int ISerialPort.BytesToRead
            {
                get
                {
                    return port.BytesToRead;
                }
            }
            void ISerialPort.Close()
            {
                port.Close();  // Fire a closing event?
                this.Dispose();
            }
            void ISerialPort.Open()
            {
                port.Open();
            }
        }

    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, February 8, 2010 4:10 PM
  • John

    Our posts have crossed so my comment is misplaced in the thread, but nice that you have found a solution. If you find something, which works in the first attempt, so that the bug can be hidden for the user, please let me know.

    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.
    Monday, February 8, 2010 4:23 PM
  • Here's code that lets the USB be unplugged and replugged with the only visible indication the data stops scrolling.

    Module Module1
      
    Sub main()
        
    Do
          Dim GPSFrm As New Form1
          
    If Not GPSFrm.ShowDialog() = Windows.Forms.DialogResult.Abort Then Exit Do
        Loop
      End Sub
    End
     Module

    Imports System.IO.Ports
    Imports System.Windows.Forms
    Public Class Form1
      
    Dim SP As SerialPort
      
    Dim WithEvents Tmr As New Timer
      
    Dim TB As New TextBox
      
    Private Sub Form1_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load
        TB.Multiline = 
    True
        TB.ScrollBars = ScrollBars.Both
        TB.Dock = DockStyle.Fill
        TB.Parent = 
    Me
        Tmr.Tag = "NewPort"
        Tmr.Start()
      
    End Sub
      Sub Tmr_Tick(ByVal sender As ObjectByVal e As EventArgs) Handles Tmr.Tick
        Tmr.Stop()
        
    Select Case CType(Tmr.Tag, String)
          
    Case "NewPort"
            Dim Ports() As String = SerialPort.GetPortNames
            
    Dim I As Integer
            For I = 0 To Ports.Length - 1
              
    If Ports(I) = "COM3" Then Exit For
            Next
            If I < Ports.Length Then
              SP = New SerialPort("COM3", 4800)
              Tmr.Tag = 
    "OpenPort"
            End If
          Case "OpenPort"
            Try
              SP.Open()
              Tmr.Tag = 
    "PortOpen"
            Catch ex As Exception
              
    'retry
            End Try
          Case "PortOpen"
            Try
              TB.AppendText(SP.ReadLine + Environment.NewLine)
            
    Catch ex As Exception
              
    Me.DialogResult = Windows.Forms.DialogResult.Abort
              
    Me.Close()
              
    Exit Sub
            End Try
        End Select
        Tmr.Start()
      
    End Sub
      Private Sub Form1_FormClosed(ByVal sender As ObjectByVal e As FormClosedEventArgs) Handles Me.FormClosed
        
    Try
          SP.Dispose()
        
    Catch ex As Exception
          
    Me.Close()
        
    End Try
      End Sub
    End
     Class

    This is a kludgy solution.  I hope someone has something more direct.


    Rudy:  Not sure what your code does, but I'll see if I can figure it out.
    Monday, February 8, 2010 8:02 PM
  • John, my code does not really "do" anything.  It is the concept. 
    What if you used your form that you just posted instead of the SerialPort object?


                ISerialPort port;
                port = new SerialPortWrapper();
                port.Open();
                port.Close();
                port.Dispose();  // I have since added a Dispose method to the interface.

    I don't have the right stuff to simulate your scenario.
    Mark the best replies as answers. "Fooling computers since 1971."
    Monday, February 8, 2010 8:30 PM
  • What if you used your form that you just posted instead of the SerialPort object?
    That doesn't change the kludge.  It just hides it from other users.  You should be able to unplug and replug a cable without having to strangle the serialport component.  Ideally it should close the port when the cable is unplugged and notify the user.  Trowing the error is alright, but not allowing disposal isn't.
    Monday, February 8, 2010 9:22 PM
  • I still think this is solvable with WMI
    please, mark this as answer if it is THE answer
    ----------------
    Diego Cattaruzza
    Microsoft MVP - Visual Basic: Development
    blog: http://community.visual-basic.it/Diego
    web site: http://www.visual-basic.it
    Tuesday, February 9, 2010 5:50 PM
  • I still think this is solvable with WMI
    Please post your code.
    Tuesday, February 9, 2010 5:54 PM
  • It 'a bit' too time-consuming process also code, but I'll translate the study-path I walked to monitor the plug-unplug of an USB device (you are referring to a port, but it's the same concept: instead of a Win32_LogicalDisk you'll refer to a Win32_PortResource).

    I discovered that .Net offers the possibility to use WMI classes through its classes exposed in the namespace System.Management.

    In particular, I found, among the WMI System Classes ( http://msdn.microsoft.com/en-us/library/aa394583(VS.85).aspx ) the events __InstanceCreationEvent ( http://msdn.microsoft.com/en-us/library/aa394649(VS.85).aspx ) and __InstanceDeletionEvent ( http://msdn.microsoft.com/en-us/library/aa394650(VS.85).aspx ) - this was the starting point of my exploration.

    From the page Using WMI ( http://msdn.microsoft.com/en-us/library/aa393964(VS.85).aspx ) I read the information that I can use System.Mangement classes to obtain informations through WMI.
    From page WMI .NET Overview ( http://msdn.microsoft.com/en-us/library/bb404655.aspx ) I surfed to WMI .NET Code Directory ( http://msdn.microsoft.com/en-us/library/ms257338.aspx ) and to How To: Receive an Event ( http://msdn.microsoft.com/en-us/library/ms257355.aspx ) and to the class ManagementEventWatcher ( http://msdn.microsoft.com/en-us/library/system.management.managementeventwatcher.aspx ).

    One of the constructors exposed by this class is used to me:
    http://msdn.microsoft.com/en-us/library/s4acy5e2.aspx

          Dim instance As New ManagementEventWatcher(eventQuery)
         
    In particular, I find that the eventQuery argument may be a generic EventQuery object ( http://msdn.microsoft.com/en-us/library/system.management.eventquery.aspx ), but also a more specific WqlEventQuery object ( http://msdn.microsoft.com/en-us/library/system.management.wqleventquery.aspx ), that requires knowledge of the particular language WQL for WMI ( http://msdn.microsoft.com/en-us/library/aa394606(VS.85).aspx ), which is a dialect of SQL.

    Considering the example shown on the page for the QueryString property ( http://msdn.microsoft.com/en-us/library/system.management.wqleventquery.querystring.aspx ), I have tried to identify the elements exposed by WMI that I needed.

    The exploration has thus continued through the WMI Reference ( http://msdn.microsoft.com/en-us/library/aa394572(VS.85).aspx ), the WMI Classes ( http://msdn.microsoft.com/en-us/library/aa394554(VS.85).aspx ), the Win32 classes ( http://msdn.microsoft.com/en-us/library/aa394084(VS.85).aspx ) until I found the name "Win32_LogicalDisk" for the type of objects to be investigated ('TargetInstance' field of the event class).

    I've consulted also, starting from WMI .NET Code Directory ( http://msdn.microsoft.com/en-us/library/ms257338.aspx ):
    How To: Retrieve Collections of Managed Objects ( http://msdn.microsoft.com/en-us/library/ms257359.aspx ),
    How To: Retrieve Information About Managed Objects by Queries ( http://msdn.microsoft.com/en-us/library/ms257346.aspx ),
    ManagementObjectSearcher ( http://msdn.microsoft.com/en-us/library/system.management.managementobjectsearcher.aspx ),
    ManagementObjectCollection ( http://msdn.microsoft.com/en-us/library/system.management.managementobjectcollection.aspx )
    and obvously ManagementObject ( http://msdn.microsoft.com/en-us/library/system.management.managementobject.aspx ).

    I thus gradually acquired all the knowledge necessary to try to implement a class that intercepts insertion and removal of a USB drive.

    The code is here: http://www.visual-basic.it/scarica.asp?ID=1020

    I think you can understand where to put the changes for your need. I hope this (all this :o))) helps.


    please, mark this as answer if it is THE answer
    ----------------
    Diego Cattaruzza
    Microsoft MVP - Visual Basic: Development
    blog: http://community.visual-basic.it/Diego
    web site: http://www.visual-basic.it
    • Edited by DiegoCattaruzza Tuesday, February 9, 2010 7:53 PM more readable form
    Tuesday, February 9, 2010 7:48 PM
  • Diego Cattaruzza:

    Your code monitors the arrival and departure of components by polling at intervals of 1 second or greater.  The messages are broadcast to applications long before your code detects the change.  I guess you would try to dispose the serialport before it receives the WM_DEVICECHANGE message.  I can''t see how it could possibly work.  This would be equivalent to using your present code to prevent the OS from seeing the arrival or removal of a disk.  The OS advises WMI, not  WMI advising the OS.
    Tuesday, February 9, 2010 7:59 PM
  • "The OS advises WMI, not  WMI advising the OS"

    yes :o))
    If you want the contrary, I'm not a magician :o))

    perhaps, you want a hook on the system, and intercept that WMmessage - but this is already out of my knowledge.

    But I think that WMI can also 'do' something on the OS, not only 'wait' OS to do something. Sure, you must struggle on the WMI pages (or find a WMI guru).
    please, mark this as answer if it is THE answer
    ----------------
    Diego Cattaruzza
    Microsoft MVP - Visual Basic: Development
    blog: http://community.visual-basic.it/Diego
    web site: http://www.visual-basic.it
    Tuesday, February 9, 2010 8:54 PM
  • "The OS advises WMI, not  WMI advising the OS"

    yes :o))
    If you want the contrary, I'm not a magician :o))

    perhaps, you want a hook on the system, and intercept that WMmessage - but this is already out of my knowledge.

    But I think that WMI can also 'do' something on the OS, not only 'wait' OS to do something. Sure, you must struggle on the WMI pages (or find a WMI guru).
    please, mark this as answer if it is THE answer
    ----------------
    Diego Cattaruzza
    Microsoft MVP - Visual Basic: Development
    blog: http://community.visual-basic.it/Diego
    web site: http://www.visual-basic.it

    WMI is just another layer on the core Win32API as is the whole .NET framework.  It's just not going to get messages quicker than the WM_MESSAGES sent to applications.  My problem is not getting notification, it's not being able to dispose the serialport after the notification.  I tried your code with "LogicalDisk" replaced with "SerialPort", but the w_EventArrived event wasn't fired. 

    Edit:

    "perhaps, you want a hook on the system, and intercept that WMmessage"

    That's what I trying to tell you, the serialport and everything else get the message at the same time.  I guess my workaround is as good as any.  The only alternative that I see is my own serial port.
    Tuesday, February 9, 2010 9:18 PM
  • I'm not sure, but I think I've understood (finally). So I must say only: 'white flag' :o)))

    excuse me for the time you wasted behind my wrong misunderstanding
    please, mark this as answer if it is THE answer
    ----------------
    Diego Cattaruzza
    Microsoft MVP - Visual Basic: Development
    blog: http://community.visual-basic.it/Diego
    web site: http://www.visual-basic.it
    Wednesday, February 10, 2010 1:52 PM
  • Not using the SerialPort seems like the best solution.  This uses CreateFile and gracefully closes the port handle when the USB cable is unplugged and opens a port handle when the USB cable is replugged.

    Imports com.ms.win32  'reference vjslib
    Imports System.Text
    Imports System.IO
    Public Class Form1
      
    Dim WithEvents Tmr As New Timer
      
    Dim hSP As Integer
      Dim PortOpen As Boolean
      
    Dim SB As New StringBuilder()
      
    Sub Tmr_Tick(ByVal sender As ObjectByVal e As EventArgs) Handles Tmr.Tick
        
    If PortOpen Then
          Dim BytesRead(0) As Integer
          Dim B(63) As Byte
          If Kernel32.ReadFile(hSP, B, 63, BytesRead, NothingThen
            Dim I, BPos As Integer
            Do
              For I = BPos To BytesRead(0) - 1
                
    If B(I) = 13 Then Exit For
                SB.Append(Chr(B(I)))
              
    Next
              If I < BytesRead(0) Then
                Console.WriteLine(SB.ToString)
                SB.Length = 0
                BPos = I + 2
              
    Else
                Exit Do
              End If
            Loop
          Else
            Kernel32.CloseHandle(hSP)
            PortOpen = 
    False
          End If
        Else
          hSP = Kernel32.CreateFile("COM3", wing.GENERIC_READ, 0, Nothing, wino.OPEN_EXISTING, 0, Nothing)
          
    Dim DCB As New DCB
          
    If Kernel32.BuildCommDCB("baud=4800 parity=N data=8 stop=1", DCB) Then _
            
    If Kernel32.SetCommState(hSP, DCB) Then PortOpen = True
        End If
      End Sub
      Private Sub Form1_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load
        Tmr.Start()
      
    End Sub
    End
     Class

    • Edited by JohnWein Wednesday, February 10, 2010 9:44 PM
    Wednesday, February 10, 2010 6:45 PM
  • Nice work, John.  Looks like a good foundation for a UsbPort class.
    Mark the best replies as answers. "Fooling computers since 1971."
    Wednesday, February 10, 2010 9:11 PM
  • Actually, the solution is much simpler:

    public Form1()
    {
        InitializeComponent();
        serialPort1.Open();
    }
    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            serialPort1.Close();
        }
        catch (Exception)
        {
        }
        serialPort1 = new SerialPort(...);
        serialPort1.Open();
    }
    

    First of all you are not supposed to use a disposed object (you're trying to re-open it). That's a no-no for any IDisposable object.

    The reason that SerialPort.Close can throw an exception is that it attempts to perform operations on the port handle (SetCommMask, EscapeCommFunction). These are going to fail on a port handle that has gone away. The good news is that the implementation of SerialPort.Dispose will call CloseHandle on the port handle even if an exception occurs (earlier) in the SerialPort.Dispose method, so the above code should work just fine.

    • Marked as answer by JohnWein Wednesday, February 10, 2010 10:48 PM
    Wednesday, February 10, 2010 9:50 PM
  • Actually, the solution is much simpler:

    public Form1()
    
    {
    
        InitializeComponent();
    
        serialPort1.Open();
    
    }
    
    private void button1_Click(object sender, EventArgs e)
    
    {
    
        try
    
        {
    
            serialPort1.Close();
    
        }
    
        catch (Exception)
    
        {
    
        }
    
        serialPort1 = new SerialPort(...);
    
        serialPort1.Open();
    
    }
    
    
    
    

    First of all you are not supposed to use a disposed object (you're trying to re-open it). That's a no-no for any IDisposable object.

    The reason that SerialPort.Close can throw an exception is that it attempts to perform operations on the port handle (SetCommMask, EscapeCommFunction). These are going to fail on a port handle that has gone away. The good news is that the implementation of SerialPort.Dispose will call CloseHandle on the port handle even if an exception occurs (earlier) in the SerialPort.Dispose method, so the above code should work just fine.


    What in the world is this?  Have you posted to the wrong thread?

    No.  You definitely posted to the right thread.  I guess I tried to Close the port, but didn't  ignore the error.

    Revised code with your solution:

    Imports System.IO.Ports
    Imports System.Windows.Forms
    Public Class Form1
      
    Dim WithEvents SP As SerialPort
      
    Dim WithEvents Tmr As New Timer
      
    Dim TB As New TextBox
      
    Private Sub Form1_Load(ByVal sender As ObjectByVal e As System.EventArgs) Handles Me.Load
        TB.Multiline = 
    True
        TB.ScrollBars = ScrollBars.Both
        TB.Dock = DockStyle.Fill
        TB.Parent = 
    Me
        Tmr.Tag = "NewPort"
        Tmr.Start()
      
    End Sub
      Sub Tmr_Tick(ByVal sender As ObjectByVal e As EventArgs) Handles Tmr.Tick
        Tmr.Stop()
        
    Select Case CType(Tmr.Tag, String)
          
    Case "NewPort"
            Dim Ports() As String = SerialPort.GetPortNames
            
    Dim I As Integer
            For I = 0 To Ports.Length - 1
              
    If Ports(I) = "COM3" Then Exit For
            Next
            If I < Ports.Length Then
              SP = New SerialPort("COM3", 4800)
              SP.ReadTimeout = 50
              Tmr.Tag = 
    "OpenPort"
            End If
          Case "OpenPort"
            Try
              SP.Open()
              Tmr.Tag = 
    "PortOpen"
            Catch ex As Exception
              
    'retry
            End Try
          Case "PortOpen"
            Try
              TB.AppendText(SP.ReadLine + Environment.NewLine)
            
    Catch ex As Exception
              Console.WriteLine(ex.GetType.ToString)
              
    If ex.GetType Is GetType(System.IO.IOException) Then
                Try
                  SP.Dispose()
                
    Catch
                End Try
                Tmr.Tag = "NewPort"
              End If
            End Try
        End Select
        Tmr.Start()
      
    End Sub
    End Class
    Wednesday, February 10, 2010 9:53 PM
  • I have a Pharos GPS-360 USB serial GPS.  I would like to unplug the USB connector and then plug it back in and reuse the GPS.  I haven't found a way to do anything with the serial port once the USB is unplugged.  Can't close or dispose the port or reestablish communication with the GPS after replugging.

        public Form1()
        {
          InitializeComponent();
          serialPort1.Open();
        }
        
    private void button1_Click(object sender, EventArgs e)
        {
          serialPort1.Close();
          serialPort1.Open();
        }

    As long as the USB in not unplugged, the button can be clicked without problem.  Unplugging and replugging gives an "The device does not recognize the command." error.  How can I reuse the serial port without closing the application?


    It is the solution to your problem.
    Wednesday, February 10, 2010 10:10 PM
  • Hi, Use this code

     

    serialPort1.close();

    while(true)

    {

    try

    {

    serialPort1.Open();

    Exit While;

    }

    catch(Exception ex)

    {

    //try opening the serial port again

    }

    }

     

    Hope this helps.

    Monday, August 15, 2011 3:14 PM
  • Hi, Use this code

     

    serialPort1.close();

    while(true)

    {

    try

    {

    serialPort1.Open();

    Exit While;

    }

    catch(Exception ex)

    {

    //try opening the serial port again

    }

    }

     

    Hope this helps.


    Really bad code.  Use the response marked as answer.
    Monday, August 15, 2011 3:22 PM
  • I have similar problem. I use usb-rs232 adapter to connect to serial port. My platform is windows forms with visual studio. In the program I display a LED to show connection status to serial port. To test the program sometimes in while program is running I plug and unplug the usb serial port adapter. The program does not crash immediately but when I move from one form to another, ( I close and re-open the serial port) and then the program crashes. Or sometimes the form starts and runs for 5-10 seconds and then crashes. It may be that this is a bug of windows platform, it happens when you unplug-plug the adapter and then open close and re-open the port again.

    From one of my collegue I learned this problem is also caused by the brand of usb-rs232 adapter. He said he used dynex, belkin and moxa adapters and their own drivers. he said he didn't had the problems with those adapters as their drivers are more stable.
    Wednesday, January 25, 2012 10:52 AM
  • I have a similar problem. My application is very complex, it has multiple processes that use IPC to communicate with each other and plug-ins to support various hardware devices. I just created a plug-in for a serial-port device and used (for testing) a USB-to-serial converter. All my calls to the SerialPort are enclosed in try-catch statements, yet if I disconnect the device from the USB port, after 10-20-30 seconds I would get the "The device does not recognize the command" exception, with the uninformative call stack, and it would crash the application host (a console application for the software's back-end). If I were to plug the device back again, it would work (i.e., continue receiving data properly) but the delayed crash would halt the entire process, so that's of no use.

    My platform is Windows 7 x64, targeting .Net 4.0 and it seems like the handling of COM ports in .Net is rather miserable. For instance, another issue I had is that a COM port that was created by a Bluetooth device (that is not connected at the moment) would show up in the list of COM ports but would cause a significant delay when trying to open it (during my auto-discover routine): the SerialPort.Open() call would block for a good 20-30 seconds before completing without throwing an exception (despite all the possible timeouts set on the SerialPort object), yet the port would not respond to any reads or writes (naturally, since the device is not there). This behavior makes no sense at all, and in general, throwing an exception that cannot be caught is totally useless, and most certainly a bug.

    This exercise is a proof of concept, so I'm not too worried (I can also support devices in a native back-end, where serial port handling is better), but I thought I'd bring it up in case anyone cares, or has a solution (that works).

    Kamen


    Currently using Visual Studio 2010 SP1, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.

    Tuesday, May 22, 2012 8:14 PM
  • I have a similar problem. My application is very complex, it has multiple processes that use IPC to communicate with each other and plug-ins to support various hardware devices. I just created a plug-in for a serial-port device and used (for testing) a USB-to-serial converter. All my calls to the SerialPort are enclosed in try-catch statements, yet if I disconnect the device from the USB port, after 10-20-30 seconds I would get the "The device does not recognize the command" exception, with the uninformative call stack, and it would crash the application host (a console application for the software's back-end). If I were to plug the device back again, it would work (i.e., continue receiving data properly) but the delayed crash would halt the entire process, so that's of no use.

    My platform is Windows 7 x64, targeting .Net 4.0 and it seems like the handling of COM ports in .Net is rather miserable. For instance, another issue I had is that a COM port that was created by a Bluetooth device (that is not connected at the moment) would show up in the list of COM ports but would cause a significant delay when trying to open it (during my auto-discover routine): the SerialPort.Open() call would block for a good 20-30 seconds before completing without throwing an exception (despite all the possible timeouts set on the SerialPort object), yet the port would not respond to any reads or writes (naturally, since the device is not there). This behavior makes no sense at all, and in general, throwing an exception that cannot be caught is totally useless, and most certainly a bug.

    This exercise is a proof of concept, so I'm not too worried (I can also support devices in a native back-end, where serial port handling is better), but I thought I'd bring it up in case anyone cares, or has a solution (that works).

    Kamen


    Currently using Visual Studio 2010 SP1, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.

    The SerialPort 4.0 no longer has the problem addressed in this thread.
    Tuesday, May 22, 2012 9:09 PM
  • The SerialPort 4.0 no longer has the problem addressed in this thread.

    Well, like i said, I am targeting .Net 4.0, the version of my System assembly is v4.0.30319, and I am getting those errors, while taking all precautions. So, something is not fixed, obviously. Whatever was done must have addressed the particular scenario some posters in this thread might have faced, but not all circumstances. I don't know what it is: it might be the particular USB-to-serial driver (Prolific 3.4.31.231) or hardware device, or it may be the way I use it (immediate, continuous polling), or something else, but it is happening. I thought since the circumstances are very similar (same resources involved, same actions to cause the problem, same error given, etc.), I thought I'd post here rather than starting a new thread.

    Kamen


    Currently using Visual Studio 2010 SP1, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.

    Tuesday, May 22, 2012 11:31 PM
  • Kamen, we experience the same problems using .net 4.0. Have you found a workaround?

    Abdul

    Monday, June 11, 2012 10:36 AM
  • Kamen, we experience the same problems using .net 4.0. Have you found a workaround?

    Abdul


    If you have the problem, use the solution in this thread.
    Monday, June 11, 2012 11:00 AM
  • Abdul, no, I haven't found a workaround. The issue is probably rooted in the serial port driver and no amount of effort in trying to sequence the open/close calls and/or surround the code with try/catch will make it go away (in mine and many others' cases that I have since identified on the Internet).

    John, I don't know why you keep insisting that there is a "solution" - the fact that it worked for you and some other people doesn't mean that it would work for everyone. I apologize if you feel that we are "hijacking" your thread, but obviously, people are finding it and reluctant to start a new thread for a seemingly identical issue.

    I think the problem comes from the way the USB-to-serial driver handles the disconnection of the device (some better than others), and the .Net libraries do not react in a graceful manner to certain responses from the driver. A COM port used to be an integral part of the system, so not much attention has been paid by the developers of both the .Net SerialPort library and the USB-to-serial drivers to live (hot) disconnection/reconnection events. For my application this is not a big problem as this was just done for testing purposes, and if needed, I could require that the device is never unplugged, but it would be nice to have a resolution of this issue.

    Kamen


    Currently using Visual Studio 2010 SP1, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.

    Monday, June 11, 2012 8:48 PM
  • "John, I don't know why you keep insisting that there is a "solution"

    There is a solution to the problem referred to in this thread.  The SerialPort has other problems not covered in this thread.  The 4.0 SerialPort corrects the immediate problem of disconnection, but it then crashes later.  This is covered in another of my threads and I believe on connect.  Using the 2.0 SerialPort with detection of plugging and unplugging and closing of the port corrects any known problems with the port.

    If you have a problem, describe it in detail in a thread on these forums or make an incident report on connect. Saying you have the same problem in this thread without posting code that demonstrates the problem does nothing to resolve it.

    Edit:  Repeating.  The 4.0 SerialPort doesn't have the exact problem covered in this thread.  It does have other problems associated with unpluging the cable, but they are discussed in other threads and connect incidents.  The reponses in this thread apply to the 2.0 SerialPort.


    • Edited by JohnWein Monday, June 11, 2012 9:50 PM
    Monday, June 11, 2012 9:34 PM
  • There are multiple problems described here and yours is only one of them. There is no need for me to post code since this is not a coding problem but a driver/library bug about which no code can get around. The action that the subject ("Serialport unplug and plug") describes, the exception text, and other symptoms are all common to what I and others who posted before me have described, and what leads the searches to this post. If you have another thread that better addresses this problem, I wish searches lead people with this problem exclusively there. I understand, it is good to have threads for specific problems, but you have to understand that it is also good to avoid flooding the forums with multiple threads addressing similar problems. But if you insist on restricting this thread (because you started it), I guess I'll just have to leave it alone.

    Kamen


    Currently using Visual Studio 2010 SP1, native C++ (Windows API) and C# (.Net, WPF), on Windows 7 64-bit; Mountain Time zone.

    Monday, June 11, 2012 11:44 PM