using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Management; using System.Threading; using System.IO.Ports; using System.Diagnostics; namespace SafeMobileLib { public class USBMonitoring { private Thread usbMonitoringThread; // the device which needs to be checked private DeviceInfo watchedDevice { get; set; } // refresh rate at which the usb detection should happen private int RefreshRateSeconds { get; set; } // remember the previous device status private bool previousDeviceStatus = false; // flag that the usb monitoring should be running or not private bool isRunning = false; public USBMonitoring(DeviceInfo watchedDecive, int refreshRateSeconds) { this.watchedDevice = watchedDecive; this.RefreshRateSeconds = refreshRateSeconds; } /// /// Start the thread which will manage the monitoring of the usb device plug & unplug /// public void StartUSBMonitoring() { if (this.isRunning) return; this.isRunning = true; usbMonitoringThread = new Thread(new ThreadStart(USBMonitoringThreadHandler)); usbMonitoringThread.Start(); } /// /// Stop the thread which is monitoring the detection of plug & unplug of the usb device /// public void StopUSBMonitoring() { this.isRunning = false; } /// /// Thread function /// private void USBMonitoringThreadHandler() { int count = -1; while (isRunning) { // wait until checking again Thread.Sleep(500); count++; if (count % (RefreshRateSeconds * 2) != 0) continue; try { bool crtDeviceStatus = false; // get the list of attached usb device var usbDevices = GetSerialPortDevices(); //GetUSBDevices(); if (watchedDevice != null && usbDevices != null) { foreach (var usbDevice in usbDevices) { //Console.WriteLine("DEV : " + usbDevice.vendorID + " | " + usbDevice.productID + " | " + usbDevice.COMPort); // iterrate through all the device and see if the watched one is connected if (usbDevice.vendorID.Equals(watchedDevice.vendorID) && usbDevice.productID.Equals(watchedDevice.productID)) { crtDeviceStatus = true; watchedDevice.COMPort = usbDevice.COMPort; break; } } // trigger event only when the device status has changed if (previousDeviceStatus != crtDeviceStatus || count == 0) OnDeviceStatusChanged(crtDeviceStatus, watchedDevice); // update previous device status previousDeviceStatus = crtDeviceStatus; } } catch (Exception ex) { Console.WriteLine("USB Monitoring Evception: " + ex.ToString()); } } Console.WriteLine("USB Monitoring Thread ended ♥♥♥"); } /// /// Get a list of connected usb devices /// /// The list of usb devices private List GetUSBDevices() { List devices = new List(); ManagementObjectCollection collection; using (var searcher = new ManagementObjectSearcher(@"Select * From Win32_USBHub")) collection = searcher.Get(); foreach (var device in collection) { devices.Add(new DeviceInfo( (string)device.GetPropertyValue("DeviceID"), (string)device.GetPropertyValue("PNPDeviceID"), (string)device.GetPropertyValue("Description") )); } collection.Dispose(); return devices; } private List GetSerialPortDevices() { List devices = new List(); ManagementObjectSearcher searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_PnPEntity"); if (searcher != null) foreach (ManagementObject queryObj in searcher.Get()) { string sInstanceName = string.Empty; string portName = string.Empty; if (queryObj["Caption"] != null && queryObj["Caption"].ToString().Contains("(COM")) { try { // get device vendor and product id sInstanceName = queryObj["DeviceID"].ToString() + " | " + queryObj["PNPDeviceID"].ToString(); // save the com port for this device portName = queryObj["Caption"].ToString(); // remove all characters before COM portName = portName.Substring(portName.IndexOf("COM")); // remove values after the COM if (portName.IndexOf(')') > 0) { portName = portName.Substring(0, portName.IndexOf(')')); } if (sInstanceName.Contains("VID_") && sInstanceName.Contains("PID_")) { string vid = sInstanceName.Substring(sInstanceName.IndexOf("VID_") + 4, 4); string pid = sInstanceName.Substring(sInstanceName.IndexOf("PID_") + 4, 4); devices.Add(new DeviceInfo(vid, pid, portName)); } } catch (Exception ex) { Utils.WriteLine(ex.ToString(), ConsoleColor.Red); } } } return devices; } /// /// Set The Baud Rate for a specific serial port /// /// Baud Rate at which the device needs to communicate /// COM port name. public void SetBaudRate(Int64 baudRate, String comPort) { SerialPort serial = new SerialPort(comPort); serial.BaudRate = (int)baudRate; } /// /// Change or Set the Parameters for the device which is watched /// /// Device parameters for the watched device public void SetWatchedDevice(DeviceInfo dev) { watchedDevice = dev; } /// /// Change or Set the Parameters for the device which is watched /// /// Vendor ID for the watched device (without VID_) /// Product ID for the watched device (without PID_) public void SetWatchedDevice(string vid, string pid) { SetWatchedDevice(new DeviceInfo(vid, pid)); } /// /// Get the status of the watched device, meaning if it is connected or not /// /// A boolean representing device status. True for connected and false otherwise public bool IsDeviceConnected() { return previousDeviceStatus; } /// /// Get the COM port name for the watched device. The name will contain even the /// COM prefix. eg.: COM32 /// /// A string representing the COM file name (including COM prefix) public string GetComPortForWatchedDevice() { if (watchedDevice == null) return ""; else return watchedDevice.COMPort; } public delegate void DeviceStatusChanged(bool isConnected, DeviceInfo device); public event DeviceStatusChanged OnDeviceStatusChanged; } }