我写了一个程序,它连接了一个键盘钩子来监听F12被按下,在收到F12被按下时,我触发一个事件来启动主程序中的一个单独进程。
这在我的主机上运行得很好,虽然机器上的任何其他应用程序都有焦点,但当全屏RDP会话被聚焦或在VMWare中运行的虚拟机被聚焦时,键盘钩子停止工作。
我使用SetWindowsHookEx设置键盘钩子,如下所示:
public static int KeyboardHook;
public void AwaitKeyboard(IntPtr handle)
{
_keyboardHookProcedure = new HookProc(KeyboardHookProc);
KeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, _keyboardHookProcedure, handle, 0);
}
然后在KeyboardHookProc方法中,我可以添加代码来处理主窗口
public static int KeyboardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0)
{
return CallNextHookEx(KeyboardHook, nCode, wParam, lParam);
}
MainWindow mainWindow = (MainWindow)Application.Current.MainWindow;
if (mainWindow != null)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
if (vkCode == mainWindow.KeyboardShortcutCode) // Keyboard shortcut pressed
{
mainWindow.KeyboardShortcutPressed();
}
}
return CallNextHookEx(KeyboardHook, nCode, wParam, lParam);
}
else
{
return CallNextHookEx(KeyboardHook, nCode, wParam, lParam);
}
}
这对于我的主机上的应用程序都很好。但是,当虚拟机或全屏RDP窗口被激活时,KeyboardHookProc方法永远不会被调用。
我已经读到建议,我可以清除钩子,并重新设置它每当活动窗口在Windows中改变。我已经尝试过了,并且得到了工作,但是重新设置钩子并没有解决问题,因为在VM或RDP中仍然没有调用KeyboardHookProc。
当我回到主机并按下F12键的那一刻,我的键盘钩子就会活跃起来,并按我需要的方式运行。
有人有什么建议吗?
感谢很可能是内核驱动程序或其他东西在钩子链中吃掉了键。就其他产品而言,这可能是有意为之。
我在我的机器上看到了同样的问题,VirtualBox在有焦点时正在吃掉我的Foobar2000热键。
WH_KEYBOARD_LL
在用户模式下几乎是最低的。你可以尝试原始输入,但我怀疑这是否会起作用。