55 lines
2.0 KiB
C#
55 lines
2.0 KiB
C#
using System;
|
|
using System.IO.Ports;
|
|
using System.Linq;
|
|
using System.Management;
|
|
|
|
namespace Elwig.Helpers {
|
|
public sealed class SerialPortWatcher : IDisposable {
|
|
|
|
private readonly ManagementEventWatcher _deviceArrivalWatcher;
|
|
private readonly ManagementEventWatcher _deviceRemovalWatcher;
|
|
|
|
private string[] _knownPorts;
|
|
|
|
public event EventHandler<string>? SerialPortConnected;
|
|
public event EventHandler<string>? SerialPortDisconnected;
|
|
|
|
public SerialPortWatcher() {
|
|
_knownPorts = SerialPort.GetPortNames();
|
|
_deviceArrivalWatcher = new ManagementEventWatcher("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2");
|
|
_deviceArrivalWatcher.EventArrived += (s, e) => OnDeviceArrived();
|
|
_deviceRemovalWatcher = new ManagementEventWatcher("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 3");
|
|
_deviceRemovalWatcher.EventArrived += (s, e) => OnDeviceRemoved();
|
|
_deviceArrivalWatcher.Start();
|
|
_deviceRemovalWatcher.Start();
|
|
|
|
}
|
|
|
|
private void OnDeviceArrived() {
|
|
string[] currentPorts = SerialPort.GetPortNames();
|
|
var newPorts = currentPorts.Except(_knownPorts).ToArray();
|
|
foreach (var port in newPorts)
|
|
SerialPortConnected?.Invoke(this, port);
|
|
_knownPorts = currentPorts;
|
|
}
|
|
|
|
private void OnDeviceRemoved() {
|
|
string[] currentPorts = SerialPort.GetPortNames();
|
|
var removedPorts = _knownPorts.Except(currentPorts).ToArray();
|
|
foreach (var port in removedPorts)
|
|
SerialPortDisconnected?.Invoke(this, port);
|
|
_knownPorts = currentPorts;
|
|
}
|
|
|
|
public void Dispose() {
|
|
try {
|
|
_deviceArrivalWatcher?.Stop();
|
|
_deviceRemovalWatcher?.Stop();
|
|
} finally {
|
|
_deviceArrivalWatcher?.Dispose();
|
|
_deviceRemovalWatcher?.Dispose();
|
|
}
|
|
}
|
|
}
|
|
}
|