Github: [https://github.com/CarterWu-M/CS-WinForm_COM-Loopback]
This article uses a Prolific USB-to-UART TTL adapter with TX and Rx connected in a loopback configuration. It introduces how to use *ManagementObjectSearcher()* to list devices in a combo box and demonstrates using a utility class, *ComPort*, to access the COM port for standard operations.



---
### Utility Class ComPort
---

```C#=
namespace serialPortStudy.Utilities
{
internal class ComPort
{
//Fields
private SerialPort _serialPort;
//Constructor
public ComPort(string szPortName, int baudRate, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One)
{
this._serialPort = new SerialPort
{
PortName = szPortName,
BaudRate = baudRate,
Parity = parity,
DataBits = dataBits,
StopBits = stopBits
};
}
//Method
public bool Open()
{
try
{
if (!this._serialPort.IsOpen)
{
// Open the device
this._serialPort.Open();
}
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
public void Close()
{
try
{
if (this._serialPort.IsOpen)
{
// Close the device
this._serialPort.Close();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public int writeStr(string szData)
{
try
{
if (this._serialPort.IsOpen)
{
// Write data (TX)
this._serialPort.Write(szData);
}
else
{
Console.WriteLine("Port is not open");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public string readStr()
{
try
{
if (this._serialPort.IsOpen)
{
// Read data (RX)
return this._serialPort.ReadExisting();
}
else
{
Console.WriteLine("Port is not open");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return string.Empty;
}
}
}
```
---
### Form1.cs
---

```C#=
using System.Management;
using serialPortStudy.Utilities;
namespace serialPortStudy
{
public partial class Form1 : Form
{
//Fields
private ComPort _comPort; //use the Utility ComPort Class
//Constructor
public Form1()
{
InitializeComponent();
searchComPortNames(); //Display available COM port devices when the form is loaded.
}
//Method
private void searchComPortNames()
{
cbComPorts.Items.Clear();
// Research COM port devices in Win32_PnPEntity
using (var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PnPEntity WHERE Name LIKE '%(COM%'"))
{
foreach (ManagementObject obj in searcher.Get())
{
string szName = obj["Name"]?.ToString();
if (szName != null)
{
// If the device exists, add it to the combo box
cbComPorts.Items.Add(szName);
}
}
if (cbComPorts.Items.Count > 0)
{
// If the combo box contains a device, select the first item to display in the combo box
cbComPorts.SelectedIndex = 0;
}
else
{
// If there is no device in the combo box, display an empty string in the combo box
cbComPorts.Text = "";
}
}
}
//...
}
}
```

If you want to use *ManagementObjectSearcher()*, remember to add a reference to *System.Management*.
---
### Refresh button
---

```C#=
namespace serialPortStudy
{
public partial class Form1 : Form
{
//Fields
private ComPort _comPort; //use the Utility ComPort Class
//...
private void btnRefresh_Click(object sender, EventArgs e)
{
// The refresh button also calls searchComPortNames() to display COM port devices
this.searchComPortNames();
}
}
}
```
---
### Open button
---


```C#=
namespace serialPortStudy
{
public partial class Form1 : Form
{
//Fields
private ComPort _comPort; //use the Utility ComPort Class
//...
// Because the combo box item includes the device name and COM port name,
// the ComPort Class only uses the COM port name to open the device.
// Therefore, getComPOrtName() will filter the device name and return only the COM port name.
private string getComPortName(string szDeviceName)
{
// Use a regular expression to filter
string szPattern = @"\(COM\d+\)";
Match match = Regex.Match(szDeviceName, szPattern);
if (match.Success)
{
// If there is a match, then return the COM port name.
return match.Value.Trim('(', ')');
}
else
{
return "";
}
}
private void btnOpen_Click(object sender, EventArgs e)
{
// Get the COM port name from the selected item in the combo box.
string szComPortName = getComPortName(cbComPorts.SelectedItem?.ToString());
// Use the ComPort class to create a new object for the field _comPort.
this._comPort = new ComPort(szComPortName, 115200);
if (this._comPort.Open())
{
// If the COM port opens successfully, then change the button's background color.
btnOpen.BackColor = Color.LightGray;
btnClose.BackColor = Color.LightGreen;
}
}
}
}
```
---
### Close button
---


```C#=
namespace serialPortStudy
{
public partial class Form1 : Form
{
//Fields
private ComPort _comPort; //use the Utility ComPort Class
//...
private void btnClose_Click(object sender, EventArgs e)
{
// Close the COM port
this._comPort.Close();
// Change the button's background color to what it was before opening.
btnOpen.BackColor = Color.Thistle;
btnClose.BackColor = Color.LightGray;
}
}
}
```
---
### Read button
---

```C#=
namespace serialPortStudy
{
public partial class Form1 : Form
{
//Fields
private ComPort _comPort; //use the Utility ComPort Class
//...
private void btnRead_Click(object sender, EventArgs e)
{
// If _comPort is not null, then read the string into the read textbox.
txtRead.Text = this._comPort?.readStr();
}
}
}
```
---
### Write button
---

```C#=
namespace serialPortStudy
{
public partial class Form1 : Form
{
//Fields
private ComPort _comPort; //use the Utility ComPort Class
//...
private void btnWrite_Click(object sender, EventArgs e)
{
// If _comPort is not null, then write the string from the write textbox.
this._comPort?.writeStr(txtWrite.Text);
}
}
}
```
---
### Youtube video
---
{%youtube Boh_ZYwYsRM %}