I am writing an application that requires an HID card reader be connected to the system. Everything works properly when a card reader is already connected when the application is started, so I know I can find the device properly. (I am using the HID classes from PM> Install-Package hidlibrary
.)
I want to add a feature where the program will display a prompt to connect a card reader if one is not found.
This is my first attempt:
public class App : Application
{
public static List<HidDevice> HidDeviceList;
// Block until device is plugged in
static ManualResetEvent m_WaitForPlugin = new ManualResetEvent(false);
// WMI Watcher for actual plug-in event
static ManagementEventWatcher watcher = new ManagementEventWatcher();
[STAThread()]
static void Main()
{
ShowSplashScreen();
FindCardReader();
CloseSplashScreen();
new App();
}
public App() : base()
{
StartupUri = new System.Uri("MainWindow.xaml", UriKind.Relative);
Run();
}
private static void FindCardReader()
{
ShowOnSplashScreen("Searching for card reader");
do
{
int VendorID = Convert.ToInt32(Settings.Default.ReaderVID, 16); // 0x0801
int ProductID = Convert.ToInt32(Settings.Default.ReaderPID, 16); // 0x0002
HidDeviceList = HidDevices.Enumerate(VendorID, ProductID).ToList();
if (HidDeviceList.Count > 0) {
break;
}
ShowOnSplashScreen("Please attach card reader...");
SetupWatcher();
m_WaitForPlugin.WaitOne();
} while (HidDeviceList.Count == 0);
}
private static void SetupWatcher()
{
WqlEventQuery query = new WqlEventQuery("SELECT * FROM Win32_DeviceChangeEvent WHERE EventType = 2");
watcher.EventArrived += new EventArrivedEventHandler(delegate(Object sender, EventArrivedEventArgs e)
{
ShowOnSplashScreen("New device detected!");
m_WaitForPlugin.Set();
});
watcher.Query = query;
watcher.Start();
}
FindCardReader()
in Main
blocks as expected, but never appears to be signalled when a new device is plugged in. (I put a breakpoint in the delegate and it was never hit.)
I am not sure how to test the WMI watcher by itself (I tested the query in PowerShell and it appears to work). I also tried starting it in a new Thread
, but the result was the same.