Last active
May 3, 2021 05:30
-
-
Save emoacht/cc2f336acc388d8921079d53a8f4e96b to your computer and use it in GitHub Desktop.
Windows service to detect device events https://github.com/emoacht/DeviceDetect/blob/master/Source/DeviceDetect.Service/DeviceDetectService.cs
This file contains 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.Diagnostics; | |
using System.Runtime.InteropServices; | |
using System.ServiceProcess; | |
public partial class DeviceDetectService : ServiceBase | |
{ | |
public DeviceDetectService() | |
{ | |
InitializeComponent(); | |
} | |
private static readonly Guid GUID_DEVINTERFACE_USB_DEVICE = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED"); | |
private IntPtr _notificationHandle; | |
protected override void OnStart(string[] args) | |
{ | |
DeviceNotification.Unregister(_notificationHandle); | |
_notificationHandle = DeviceNotification.Register(this.ServiceHandle, GUID_DEVINTERFACE_USB_DEVICE); | |
} | |
protected override void OnStop() | |
{ | |
DeviceNotification.Unregister(_notificationHandle); | |
_notificationHandle = IntPtr.Zero; | |
} | |
protected override void OnCustomCommand(int command) | |
{ | |
switch (command) | |
{ | |
case DeviceNotification.SERVICE_CONTROL_DEVICEEVENT: | |
Debug.WriteLine("USB device event received!"); | |
this.EventLog.WriteEntry("USB device event received!"); | |
break; | |
} | |
} | |
} | |
public static class DeviceNotification | |
{ | |
[DllImport("User32.dll", CharSet = CharSet.Auto, SetLastError = true)] | |
private static extern IntPtr RegisterDeviceNotification( | |
IntPtr hRecipient, | |
IntPtr NotificationFilter, | |
uint Flags); | |
[DllImport("User32.dll")] | |
[return: MarshalAs(UnmanagedType.Bool)] | |
private static extern bool UnregisterDeviceNotification(IntPtr Handle); | |
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] | |
private struct DEV_BROADCAST_DEVICEINTERFACE | |
{ | |
public uint dbcc_size; | |
public uint dbcc_devicetype; | |
public uint dbcc_reserved; | |
public Guid dbcc_classguid; | |
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 255)] | |
public string dbcc_name; | |
} | |
private const int DEVICE_NOTIFY_SERVICE_HANDLE = 0x00000001; | |
private const int DBT_DEVTYP_DEVICEINTERFACE = 0x00000005; | |
public const int SERVICE_CONTROL_DEVICEEVENT = 0x0000000B; | |
/// <summary> | |
/// Registers to device events. | |
/// </summary> | |
/// <param name="serviceHandle">Service status handle</param> | |
/// <param name="classGuid">Device interface class Guid</param> | |
/// <returns>Device notification handle</returns> | |
public static IntPtr Register(IntPtr serviceHandle, Guid classGuid) | |
{ | |
var dbcc = new DEV_BROADCAST_DEVICEINTERFACE | |
{ | |
dbcc_size = (uint)Marshal.SizeOf<DEV_BROADCAST_DEVICEINTERFACE>(), | |
dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE, | |
dbcc_classguid = classGuid | |
}; | |
var buffer = IntPtr.Zero; | |
try | |
{ | |
buffer = Marshal.AllocHGlobal((int)dbcc.dbcc_size); | |
Marshal.StructureToPtr(dbcc, buffer, true); | |
return RegisterDeviceNotification( | |
serviceHandle, | |
buffer, | |
DEVICE_NOTIFY_SERVICE_HANDLE); | |
} | |
catch (Exception ex) | |
{ | |
Debug.WriteLine($"Failed to register.\r\n{ex}"); | |
return IntPtr.Zero; | |
} | |
finally | |
{ | |
if (buffer != IntPtr.Zero) | |
Marshal.FreeHGlobal(buffer); | |
} | |
} | |
/// <summary> | |
/// Unregisters from device events. | |
/// </summary> | |
/// <param name="notificationHandle">Device notification handle</param> | |
public static void Unregister(IntPtr notificationHandle) | |
{ | |
if (notificationHandle != IntPtr.Zero) | |
UnregisterDeviceNotification(notificationHandle); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment