使用远程桌面后,键盘挂钩停止工作

时间:2011-02-21 12:18:19

标签: c# keyboard-hook

我遇到以下问题:

我启动任何远程桌面会话后,我的全局键盘挂钩停止工作,即使会话已关闭,挂钩也根本不起作用。

这是我的钩子的代码

public class KeyboardHooker : IDisposable
    {
        private IntPtr _hhook;
        private static User32.LowLevelKeyboardProc _delegate;

        public KeyboardHooker()
        {
            _delegate = new User32.LowLevelKeyboardProc(HookCallback);
        }

        public void SetHook()
        {
            if (IsHookSetted)
                return;

            using (Process curProcess = Process.GetCurrentProcess())
            using (ProcessModule curModule = curProcess.MainModule)
            {
                _hhook = User32.SetWindowsHookEx(User32.WH_KEYBOARD_LL, _delegate, Kernel32.GetModuleHandle(curModule.ModuleName), 0);
            }
        }

        public void ReleaseHook()
        {
            if (IsHookSetted)
            {
                User32.UnhookWindowsHookEx(_hhook);
                _hhook = IntPtr.Zero;
            }
        }

        public bool IsHookSetted
        {
            get { return _hhook != IntPtr.Zero; }
        }

        private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                bool handled = false;

                switch (wParam.ToInt32())
                {
                    case Messages.WM_SYSKEYDOWN:
                    case Messages.WM_KEYDOWN:
                        int vkCode = Marshal.ReadInt32(lParam);
                        Keys keys = ExtractKey(vkCode);
                        RaiseKeyDown(keys, ref handled);
                        break;
                    case Messages.WM_SYSKEYUP:
                    case Messages.WM_KEYUP:
                        vkCode = Marshal.ReadInt32(lParam);
                        keys = ExtractKey(vkCode);
                        RaiseKeyUp(keys, ref handled);
                        break;
                }
                if (handled)
                    return IntPtr.Add(IntPtr.Zero, 1);
            }
            GC.KeepAlive(this);
            return User32.CallNextHookEx(_hhook, nCode, wParam, lParam);
        }

        private Keys ExtractKey(int wParam)
        {
            Keys key = (Keys)wParam;
            return key;
        }
        #region Events

        public event KeyEventHandler KeyDown;
        public event KeyEventHandler KeyUp;

        private void RaiseKeyUp(Keys keys, ref bool handled)
        {
            if (KeyUp != null)
            {
                KeyEventArgs e = new KeyEventArgs(keys);
                KeyUp(this, e);
                handled = e.Handled;
            }
        }


        private void RaiseKeyDown(Keys keys, ref bool handled)
        {
            if (KeyDown != null)
            {
                KeyEventArgs e = new KeyEventArgs(keys);
                KeyDown(this, e);
                handled = e.Handled;
            }
        }
        #endregion

        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            ReleaseHook();
        }

        #endregion
    }

有人知道如何解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

我找到了解决方案。它发生在我的代码处理键输入很长一段时间并且Windows通过超时分离了我的钩子。现在我在单独的线程中处理每个操作并且钩子工作正常。