I was trying to get when the user press some combination of keys trigger an event in our app (nothing malicious just and alert to our service)
so SetWindowsHookEx with WH_KEYBOARD_LL should acomplish that, works as expectect in some Windows version for both cases locked and normal state, the issue comes with "some" versions, for example in:
Windows 10 Pro 1803 17134.885 doesn't work
Windows 10 Pro 1803 17134.950 here it works
But can be other thing different from the version, some antivirus? [checked with/without] some register key entry?
I read many articles and tried different approachs but all with the same result, so anyone can help me with what should I check? because in some pc's works but others doesn't, looks something apart from the code...
The issue is just in lock screen (tried in different pcs), "normal" mode works everywhere, tried and working during the lock screen image in about 7 pc's (with different Win10 versions) but doesn't in about 4 (Windows 7, other Windows 10 with different users/locations) doesn't looks have something in common (maybe, but don't know where to search it)
The code used (C# Net Framework 4.5, Windows Forms):
public class KeyboardListener
{
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private const int WM_SYSKEYDOWN = 0x0104;
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardListenerProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
public delegate IntPtr KeyboardListenerProc(int nCode, IntPtr wParam, IntPtr lParam);
private KeyboardListenerProc _proc;
private IntPtr _hookID = IntPtr.Zero;
public KeyboardListener()
{
_proc = HookCallback;
}
public void HookKeyboard()
{
_hookID = SetHook(_proc);
}
public void UnHookKeyboard()
{
UnhookWindowsHookEx(_hookID);
}
private IntPtr SetHook(KeyboardListenerProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
}
}
private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
//In some cases doesn't send anything in lock screen here, just the key "enter" after the password
//while in most of the cases before you put the password you get the combination
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN || wParam == (IntPtr)WM_SYSKEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
//TODO: send to service vkCode
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
}
The above code works in some cases in the lock screen image (I don't need it while the password input is present), want to know why in some cases works while in others doesn't
Tried also changing
private IntPtr SetHook(LowLevelKeyboardProc proc)
{
//using (Process curProcess = Process.GetCurrentProcess())
//using (ProcessModule curModule = curProcess.MainModule)
//{
// return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
//}
IntPtr hook = SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle("user32"), 0);
if (hook == IntPtr.Zero)
{
throw new System.ComponentModel.Win32Exception();
}
return hook;
}