Created
January 9, 2019 14:20
-
-
Save M0n7y5/b45669c238ff3f2602c1859b3829137c to your computer and use it in GitHub Desktop.
Elegant Serial Port Connect / Disconnect Detection using WMI and C#
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Management; | |
namespace WMITester | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
try | |
{ | |
// I ended up using MSSerial_PortName from root\WMI, because Win32_SerialPort from root\CIMV2 won't detect my FTDI Serial Converter | |
// (but it's showed up properly in Device manager) and it's also firing multiple events per device disconnecting/connecting | |
// more info here https://stackoverflow.com/questions/19840811/list-of-serialports-queried-using-wmi-differs-from-devicemanager | |
ManagementScope managementScope = new ManagementScope(@"root\WMI"); | |
// Declaring queries for creation and deletion events of MSSerial_PortName instances | |
// we want pull query every 1 second so we get small latency between | |
WqlEventQuery creatonQuery = new WqlEventQuery("__InstanceCreationEvent", TimeSpan.FromSeconds(1), | |
"TargetInstance ISA 'MSSerial_PortName'"); | |
WqlEventQuery deletionQuery = new WqlEventQuery("__InstanceDeletionEvent", TimeSpan.FromSeconds(1), | |
"TargetInstance ISA 'MSSerial_PortName'"); | |
// Initalize ManagementEventWatchers each for attach and detach | |
ManagementEventWatcher deviceAttachWatcher = new ManagementEventWatcher(managementScope, creatonQuery); | |
ManagementEventWatcher deviceDetachWatcher = new ManagementEventWatcher(managementScope, deletionQuery); | |
Console.WriteLine("Waiting for an events..."); | |
// Event handlers | |
deviceAttachWatcher.EventArrived += deviceAttachWatcher_EventArrived; | |
deviceDetachWatcher.EventArrived += DeviceDetachWatcher_EventArrived; | |
// Connect to our scope | |
managementScope.Connect(); | |
// Start listening for events | |
deviceAttachWatcher.Start(); | |
deviceDetachWatcher.Start(); | |
} | |
catch( Exception ex) | |
{ | |
Console.WriteLine(ex); | |
} | |
while (true) { } | |
} | |
private static void DeviceDetachWatcher_EventArrived(object sender, EventArrivedEventArgs e) | |
{ | |
// Get instance of MSSerial_PortName class | |
// More info about that class http://wutils.com/wmi/root/wmi/msserial_portname/ | |
var instance = e.NewEvent.GetPropertyValue("TargetInstance") as ManagementBaseObject; | |
// Now we are ready to access properties of MSSerial_PortName itself | |
Console.WriteLine($"Port: {instance.GetPropertyValue("PortName")} disconnected!"); | |
} | |
private static void deviceAttachWatcher_EventArrived(object sender, EventArrivedEventArgs e) | |
{ | |
// Get instance of MSSerial_PortName | |
var instance = e.NewEvent.GetPropertyValue("TargetInstance") as ManagementBaseObject; | |
// Now we are ready to access properties of MSSerial_PortName itself | |
Console.WriteLine($"Port: {instance.GetPropertyValue("PortName")} connected!"); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This will not work if no COM port was connected prior to application execution. The code will throw error on first watcher
Start()
method.