SafeDispatch/SafeMobileLIB_DLL/USBMonitoring.cs
2024-02-22 18:43:59 +02:00

242 lines
8.7 KiB
C#

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;
}
/// <summary>
/// Start the thread which will manage the monitoring of the usb device plug & unplug
/// </summary>
public void StartUSBMonitoring()
{
if (this.isRunning)
return;
this.isRunning = true;
usbMonitoringThread = new Thread(new ThreadStart(USBMonitoringThreadHandler));
usbMonitoringThread.Start();
}
/// <summary>
/// Stop the thread which is monitoring the detection of plug & unplug of the usb device
/// </summary>
public void StopUSBMonitoring()
{
this.isRunning = false;
}
/// <summary>
/// Thread function
/// </summary>
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 ♥♥♥");
}
/// <summary>
/// Get a list of connected usb devices
/// </summary>
/// <returns>The list of usb devices</returns>
private List<DeviceInfo> GetUSBDevices()
{
List<DeviceInfo> devices = new List<DeviceInfo>();
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<DeviceInfo> GetSerialPortDevices()
{
List<DeviceInfo> devices = new List<DeviceInfo>();
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;
}
/// <summary>
/// Set The Baud Rate for a specific serial port
/// </summary>
/// <param name="baudRate">Baud Rate at which the device needs to communicate</param>
/// <param name="comPort">COM port name. </param>
public void SetBaudRate(Int64 baudRate, String comPort)
{
SerialPort serial = new SerialPort(comPort);
serial.BaudRate = (int)baudRate;
}
/// <summary>
/// Change or Set the Parameters for the device which is watched
/// </summary>
/// <param name="dev">Device parameters for the watched device</param>
public void SetWatchedDevice(DeviceInfo dev)
{
watchedDevice = dev;
}
/// <summary>
/// Change or Set the Parameters for the device which is watched
/// </summary>
/// <param name="vid">Vendor ID for the watched device (without VID_)</param>
/// <param name="pid">Product ID for the watched device (without PID_)</param>
public void SetWatchedDevice(string vid, string pid)
{
SetWatchedDevice(new DeviceInfo(vid, pid));
}
/// <summary>
/// Get the status of the watched device, meaning if it is connected or not
/// </summary>
/// <returns>A boolean representing device status. True for connected and false otherwise</returns>
public bool IsDeviceConnected()
{
return previousDeviceStatus;
}
/// <summary>
/// Get the COM port name for the watched device. The name will contain even the
/// COM prefix. eg.: COM32
/// </summary>
/// <returns>A string representing the COM file name (including COM prefix)</returns>
public string GetComPortForWatchedDevice()
{
if (watchedDevice == null)
return "";
else
return watchedDevice.COMPort;
}
public delegate void DeviceStatusChanged(bool isConnected, DeviceInfo device);
public event DeviceStatusChanged OnDeviceStatusChanged;
}
}