My C# application uses the COM ports. I am having some difficulty that should be common to most programs. I need to get an event when the list of Portnames changes. I have a selection box where the user can choose from teh list of available port names. Does anyone have a snippet of code for this? Thank You.
1) Click Start. 2) Click Control Panel in the Start menu. 3) Click Device Manager in the Control Panel. 4) Click + next to Port in the Device Manager to display the port list.
It can also be done with help of "ManagementEventWatcher":
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.Composition;
using System.Linq;
using System.Text;
using System.Management;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
namespace HmxFlashLoader
{
/// <summary>
/// Make sure you create this watcher in the UI thread if you are using the com port list in the UI
/// </summary>
[Export]
[PartCreationPolicy(CreationPolicy.Shared)]
public sealed class SerialPortWatcher : IDisposable
{
public SerialPortWatcher()
{
_taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
ComPorts = new ObservableCollection<string>(SerialPort.GetPortNames().OrderBy(s => s));
WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent");
_watcher = new ManagementEventWatcher(query);
_watcher.EventArrived += (sender, eventArgs) => CheckForNewPorts(eventArgs);
_watcher.Start();
}
private void CheckForNewPorts(EventArrivedEventArgs args)
{
// do it async so it is performed in the UI thread if this class has been created in the UI thread
Task.Factory.StartNew(CheckForNewPortsAsync, CancellationToken.None, TaskCreationOptions.None, _taskScheduler);
}
private void CheckForNewPortsAsync()
{
IEnumerable<string> ports = SerialPort.GetPortNames().OrderBy(s => s);
foreach (string comPort in ComPorts)
{
if (!ports.Contains(comPort))
{
ComPorts.Remove(comPort);
}
}
foreach (var port in ports)
{
if (!ComPorts.Contains(port))
{
AddPort(port);
}
}
}
private void AddPort(string port)
{
for (int j = 0; j < ComPorts.Count; j++)
{
if (port.CompareTo(ComPorts[j]) < 0)
{
ComPorts.Insert(j, port);
break;
}
}
}
public ObservableCollection<string> ComPorts { get; private set; }
#region IDisposable Members
public void Dispose()
{
_watcher.Stop();
}
#endregion
private ManagementEventWatcher _watcher;
private TaskScheduler _taskScheduler;
}
}
COM ports changing is a rare event, not a common one.
The easiest way would be to have a timer and every 10-30 seconds enumerate the list of COM ports and if changed, update the list.
Better still, provide a "refresh list" button - the list will basically only change if the user has plugged a USB Serial adapter in.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With