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;
}
}