Depending on the version of the CLR and Windows, you will have some specific problems using Windows Hooks.
- A WH_KEYBOARD/WH_KEYBOARD_LL keyboard hooks require a message loop to operate correctly. The keyboard event is posted to the installing thread's message queue before generating the call to hook delegate.
- Windows Vista and later will not allow hooks from lower privilege processes to see activity in higher privilege process. So you may or may not get the keyboard event depending on what process currently has the input focus.
- Once you have hooked keyboard events, you will need to have a start and stop sentinel generated by the card reader to indicate that you should capture the remaining input. Whether or not this is achievable is going to depend on the ability to configure the card reader.
Having said all of that, it is certainly possible to achieve the desired result using WH_KEYBOARD or WH_KEYBOARD_LL hooks. If you decide to go that route, I suggest that you use alternating Left-Ctrl and Right-Control keypresses as start and stop sentinels from the reader (assuming it is capable of doing so).
Also, if you do end up with a Windows Hook, you will need to install the hook from a background thread rather than your application's main thread as you are required to process keyboard events within a certain amount of time. If you take longer than Windows allows, the hook will be ignored.
As an alternate to Windows Hooks, you may use DirectInput. Honestly, I've never tried this approach but the concept seems reasonable and eliminates some of the uncertainty of Windows Hooks.
I'm assuming that since you are asking for global keyboard events, that your card reader is some variety of USB HID device. You can validate that your card reader shows up as a DirectInput device by running DxDiag. The device should appear on the Input tab if it will be accessible. There appear to be various managed assemblies for DirectX available.
If you are not limited to the type of card reader that you have, you might be better off with a serial based reader. With it you would not be completing with other applications for the device's output.
After some further thought, I considered that you may be able to access the HID device directly and perform the keyboard translations using standard Win32 API. In looking along that route, I came across the Raw Input API. Using this you should be able to register for raw input for all keyboard devices, then determine at input time what device actually generated the event. Eliminating the need for start and stop sentinels from the reader.
Even better, the API send messages to distinguish between input generated when the window is the foreground window and when it is not. With this API you will still need to create a window and message loop on a background thread, but it should be much cleaner than the Windows Hook method.
See Using Raw Input from C# to handle multiple keyboards on CodeProject for an example application reading raw input in C#.