1

次の問題があります。

リモート デスクトップ セッションを開始すると、グローバル キーボード フックが機能しなくなります。セッションが閉じられていても、フックがまったく機能しません。

これが私のフックのコードです

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
    }

この問題を解決する方法を知っている人はいますか?

4

1 に答える 1

3

私は解決策を見つけました。コードがキー入力を長時間処理し、Windows がタイムアウトによってフックを切り離したときに発生します。今、私は各操作を別々のスレッドで処理し、フックは正常に動作します。

于 2011-04-01T14:08:44.910 に答える