L
L
Ledington2021-06-09 12:04:07
C++ / C#
Ledington, 2021-06-09 12:04:07

How to do a COM Port Scan and Add to ComboBox?

Good afternoon!
I am at the very beginning of my journey into programming in this language, so I can ask quite simple questions for some.
There is a simple task like, to scan COM ports on a computer. There are no direct ones, there is a COM port connected via a USB adapter. In the manager it is displayed as USB-SERIAL CH340 (COM3) .
It is necessary to check whether it is free or not, and whether it is alive, and add it to the ComboBox.
I read various forums and came up with this code:

using System;
using System.IO;
using System.IO.Ports;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace COM_test_2
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void connect ()
        {
            string[] ports = SerialPort.GetPortNames();
            SerialPort[] serialPort = new SerialPort[ports.Length];
            foreach (string port in ports)
            {
                int i = Array.IndexOf(ports, port);
                //serialPort[i] = new SerialPort();
                serialPort[i].PortName = port;
                serialPort[i].BaudRate = 9600;
                serialPort[i].Open();

                serialPort[i].DataReceived += serialPort_DataReceived;
                comboBox.Items.Add(port);
            }
        }

        private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            SerialPort serialPort1 = sender as SerialPort;
            byte[] data = new byte[serialPort1.BytesToRead]; 
            Stream portStream = serialPort1.BaseStream;
            portStream.Read(data, 0, data.Length);
        }
    }
}


The code does not cause any compilation errors, it runs, but there is nothing in the ComboBox.
What's wrong? How to see COM3 in ComboBox?

Answer the question

In order to leave comments, you need to log in

5 answer(s)
A
Alexander Volkov, 2021-06-09
@a_volkov1987

I'm not a real programmer, but I did this and everything works:
When loading the form, we subtract the list of ports and shove them into the combobox

private void Main_Load(object sender, EventArgs e)
        {
            var portNames = SerialPort.GetPortNames();
            portSelectorComboBox.Items.AddRange(portNames);
        }

The element selected in the combobox is thrown into a variable
private void portSelectorComboBox_TextChanged(object sender, EventArgs e)
        {
            _portName = portSelectorComboBox.SelectedItem.ToString();
        }

On pressing the OpenButton button, we are trying to connect
private void portOpenButton_Click(object sender, EventArgs e)
        {
            try
            {
                port = new SerialPort(_portName, 115200, Parity.None, 8, StopBits.Two);
                port.ReceivedBytesThreshold = 1;
                port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
                port.Open();
                portStatusText.Text = "Ok, port open";
            }
            catch (Exception)
            {
                portStatusText.Text = "Error";
                MessageBox.Show("неправильно выбран порт, попробуйте еще раз");
            }
        }

Well, let's implement the reading of what has come
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

        }

C
cicatrix, 2021-06-09
@cicatrix

At one time I did the enumeration of serial ports like this, but I'm not sure that this is good.
It would also be interesting to know if it can be done more elegantly:

using System.Management;

public static Dictionary<string, ManagementBaseObject> EnumerateComPorts()
{
    Dictionary<string, ManagementBaseObject> result = new Dictionary<string, ManagementBaseObject>();
    string[] ports = SerialPort.GetPortNames();
    foreach (string port in ports)
    {
        using (var entitySearcher = new ManagementObjectSearcher(
            "root\\CIMV2", $"SELECT * FROM Win32_PnPEntity WHERE Caption LIKE '%{port}%'"))
        {
            var matchingEntity = entitySearcher.Get().Cast<ManagementBaseObject>().FirstOrDefault();
            if (null != matchingEntity)
            {
                result.Add(port, matchingEntity);
            }
        } // using
    } // foreach
    return result;
} // EnumerateComPorts

Next, I already made a Listener on the desired port and waited for data:
public RS232Listener(string portname)
        {
            m_queue = new Queue<string>();
            try
            {
                if (null != m_port)
                {
                    m_port.Close();
                    m_port.Dispose();
                    GC.Collect();
                    GC.WaitForPendingFinalizers();
                }
                m_port = new SerialPort(portname, 9600, Parity.None, 8, StopBits.One);
                m_port.DataReceived += this.M_port_DataReceived;
                m_port.ErrorReceived += this.M_port_ErrorReceived;
                m_port.Open();
            } // try
            catch(Exception ex)
            {
                Logger.LogError("RS232Listener constructor", ex.Message, ex);
                ErrorMessage = ex.Message;
                ErrorState = true;
            }
        } // RS232Listener constructor

D
d-stream, 2021-06-09
@d-stream

Sequentially sorting through 256 com ports, and even getting hacks in 99% of cases, is a long thing,
but this is apparently the only way to reliably determine all ports
, I would do attempts to open them in separate threads (background) and mark them as potentially available
, at least will allow you not to freeze the UI for minutes ... well, in the general case, if you "spit" at once 256 parallel checks, then you can wait for the end of the result in 30 seconds.

A
Alexey Bereznikov, 2021-06-10
@gdt

Here https://stackoverflow.com/a/1394301/1828989 all the most popular ways to detect ports are listed, choose according to your taste :)

L
lonelymyp, 2021-06-14
@lonelymyp

As far as I remember, an attempt to open an unconnected port can hang the software, so you should immediately kill the thread if there is no instant result, without waiting for the timeout.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question