2

I am trying to dynamically add serial ports to a combobox as the user inserts a usb. I have the code below so far. What I am having trouble in is that i cannot delete the serial port when the user pulls out the usb.

 Public Sub adding_items()


        Do While x > 0
            Dim Ports As String() = IO.Ports.SerialPort.GetPortNames()
            For Each Port In Ports
                If ComboBox1.Items.Contains(Port) Then


                Else

                    ComboBox1.Items.Add(Port)
                End If


                If ComboBox2.Items.Contains(Port) Then

                Else

                    ComboBox2.Items.Add(Port)
                End If
                If ComboBox3.Items.Contains(Port) Then


                Else
                    ComboBox3.Items.Add(Port)
                End If
            Next Port

            'deleting = New Threading.Thread(AddressOf deleting_items)
            'deleting.Start()

            'Thread.Sleep(5000)


        Loop





    End Sub

Please note I am not opening or closing any serial ports, just assigning them to the comboboxes.

Rahul
  • 903
  • 1
  • 10
  • 27
TheNoob
  • 185
  • 1
  • 12
  • Serial ports date from the stone age, they don't have plug & play support. So detecting that you jerked a USB connector is not practical. And rarely comes to a good end when the port is opened, using the "Safely remove hardware" try icon is a hard requirement. Don't do it. – Hans Passant Dec 27 '17 at 19:40
  • @HansPassant I understand the issues that could be faced here. Like the usb still installing the required software and stuff. I couldnt figure out a way to fix that, but for now i am going with this.Do you have a better approach? – TheNoob Dec 27 '17 at 19:42

2 Answers2

3

I think the easiest way for you to do this is by saving the the port list in each Do while loop and compare it to the new list you get by calling IO.Ports.SerialPort.GetPortNames() in the following loop. One way of doing this is finding the set difference between both lists. For example:

Public Sub adding_items()
    'List of ports to compare ports in current list as opposet to previous list
    Dim previousPorts As String() = Nothing
    Do While x > 0
        Dim Ports As String() = IO.Ports.SerialPort.GetPortNames()
                For Each Port In Ports
                    If Not ComboBox1.Items.Contains(Port) Then
                        ComboBox1.Items.Add(Port)
                    End If

                    If Not ComboBox2.Items.Contains(Port) Then
                        ComboBox2.Items.Add(Port)
                    End If

                    If Not ComboBox3.Items.Contains(Port) Then
                        ComboBox3.Items.Add(Port)
                    End If
                Next Port
        If previousPorts is Nothing Then
            previousPorts = Ports
        Else
            ' Get the ports from previousPorts that are nor part of Ports
            Dim differenceQuery = previousPorts.Except(Ports)  
            For Each deletedPort in differenceQuery
                ComboBox1.Items.RemovedeletedPort 
                ComboBox2.Items.RemovedeletedPort
                ComboBox3.Items.RemovedeletedPort  
            Next deletedPort 
            'Save the current port list to compare in the next loop.
            previousPorts = Ports
        End If

        'deleting = New Threading.Thread(AddressOf deleting_items)
                'deleting.Start()

                'Thread.Sleep(5000)
    Loop

    End Sub
Emilio Lucas Ceroleni
  • 1,559
  • 2
  • 9
  • 13
  • This is going to eat CPU like crazy and will freeze his program. Either do it in a background thread with a delay, or use a `Timer` instead of a loop. – Visual Vincent Dec 27 '17 at 19:21
  • I can see that, I just made a couple of changes to the original code posted by the author focusing on his issue about the ports that are not connected anymore. If you check both codes out (the author's and mine) you may notice his commented out line `'Thread.Sleep(5000)` and that in the `Do While x > 0` expression `x`'s scope is from a higher level than that of `adding_items()` so I can't tell how the final implementation of this method may be. – Emilio Lucas Ceroleni Dec 27 '17 at 19:36
  • Its getting called on a different thread. Application is pretty basic , dont think this would be an issue. Just a couple of USBs – TheNoob Dec 27 '17 at 19:39
  • @TheNoob : How are you accessing UI controls from a background thread? Have you changed the `CheckForIllegalCrossThreadCalls` property? Because _if_ you have done so you should **stop at once!** Doing so is very bad practice and definitely not the right way to go. – Visual Vincent Dec 27 '17 at 21:06
  • @EmilioCeroleni : I understand, though as an answerer I always think one should try to fix (or at least point out) as many problems as possible in the OP's code, so that they're utilizing as little bad practice as possible ;). I never implied that your answer is bad though. It is definitely a valid answer. – Visual Vincent Dec 27 '17 at 21:12
  • @VisualVincent Yes, for this example i was, although i am using the invoke function as of now. I havent figured out how to use the ReportProgress command. I noticed on the internet that using the invoke function is not preferable as well. – TheNoob Dec 28 '17 at 13:37
  • @TheNoob : It is preferable if you use it correctly. See this: https://stackoverflow.com/a/45571728/3740093 -- The best and most simple way is to use my extension method. – Visual Vincent Dec 28 '17 at 13:59
  • @VisualVincent Well, thank you for that. I am doing it the way you have mentioned in the example. – TheNoob Dec 28 '17 at 14:45
  • @VisualVincent A question Vincent, can i use invoke to write to com ports simultaneously while another thread is writing to other ports – TheNoob Dec 28 '17 at 16:33
  • @TheNoob : I'm not familiar with COM, but what `Invoke` does is that it moves execution of a method to your application's UI thread. What I can say is that if you invoke _**every**_ COM write then they will at least not be affected by the concurrency caused by writing from multiple threads at the same time. However, whether concurrency is actually _an issue_ for COM, I do not know. – Visual Vincent Dec 28 '17 at 19:24
1

Sorry, C# here but it should be similar. Does it have to refresh while the combobox list is held open? If not, I would recommend just refreshing the combobox on the DropDown Event. Every time the user clicks the combobox it should refresh the list.

private void ComboBoxCommPort_DropDown(object sender, EventArgs e)
{
    ComboBoxCommPort.DataSource = SerialPort.GetPortNames();
}
Baddack
  • 1,947
  • 1
  • 24
  • 33
  • That would be a nice feature to have, that when the user pulls it out and the combobox is held open it shows the change. – TheNoob Dec 28 '17 at 15:19