Блокировка сочетаний клавиш с помощью c #

Я использую приведенный ниже код, чтобы отключить Alt + Tab, Alt + Esc, Ctrl + Esc и клавишу Windows, но почему-то это не работает. Пожалуйста, помогите мне это исправить.

namespace BlockShortcuts
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private delegate int LowLevelKeyboardProcDelegate(int nCode, int
           wParam, ref KBDLLHOOKSTRUCT lParam);

        [DllImport("user32.dll", EntryPoint = "SetWindowsHookExA", CharSet = CharSet.Ansi)]
        private static extern int SetWindowsHookEx(
           int idHook,
           LowLevelKeyboardProcDelegate lpfn,
           int hMod,
           int dwThreadId);

        [DllImport("user32.dll")]
        private static extern int UnhookWindowsHookEx(int hHook);

        [DllImport("user32.dll", EntryPoint = "CallNextHookEx", CharSet = CharSet.Ansi)]
        private static extern int CallNextHookEx(
            int hHook, int nCode,
            int wParam, ref KBDLLHOOKSTRUCT lParam);

        const int WH_KEYBOARD_LL = 13;
        private int intLLKey;
        private KBDLLHOOKSTRUCT lParam;

        private struct KBDLLHOOKSTRUCT
        {
            public int vkCode;
            int scanCode;
            public int flags;
            int time;
            int dwExtraInfo;
        }

        private int LowLevelKeyboardProc(
            int nCode, int wParam,
            ref KBDLLHOOKSTRUCT lParam)
        {
            bool blnEat = false;
            switch (wParam)
            {
                case 256:
                case 257:
                case 260:
                case 261:
                    //Alt+Tab, Alt+Esc, Ctrl+Esc, Windows Key
                    if (((lParam.vkCode == 9) && (lParam.flags == 32)) ||
                    ((lParam.vkCode == 27) && (lParam.flags == 32)) || ((lParam.vkCode ==
                    27) && (lParam.flags == 0)) || ((lParam.vkCode == 91) && (lParam.flags
                    == 1)) || ((lParam.vkCode == 92) && (lParam.flags == 1)) || ((true) &&
                    (lParam.flags == 32)))
                    {
                        blnEat = true;
                    }
                    break;
            }

            if (blnEat)
                return 1;
            else return CallNextHookEx(0, nCode, wParam, ref lParam);

        }

        private void KeyboardHook(object sender, EventArgs e)
        {
            intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL,new LowLevelKeyboardProcDelegate(LowLevelKeyboardProc),
                       System.Runtime.InteropServices.Marshal.GetHINSTANCE(
                       System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);
        }

        private void ReleaseKeyboardHook()
        {
            intLLKey = UnhookWindowsHookEx(intLLKey);
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
                KeyboardHook(this, e);
            else
                ReleaseKeyboardHook();
        }
    }
}

person Anuya    schedule 24.07.2009    source источник
comment
@Tom Ritter, что было отредактировано в приведенном выше коде. Спасибо.   -  person Anuya    schedule 24.07.2009
comment
@karthik, вы можете найти изменения на странице stackoverflow.com/revisions/1175675/list   -  person Robert Harvey    schedule 24.07.2009


Ответы (2)


Код в целом работает нормально. Эффект, который вы наблюдаете, вероятно, связан с работой в отладчике Visual Studio, что обычно подразумевает, что вы работаете в Visual Studio Хостинговый процесс (vshost.exe).

Это означает, что вызов System.Reflection.Assembly.GetExecutingAssembly() в вашей KeyboardHook() функции возвращает vshost.exe, а не ваш исполняемый файл, следовательно, желаемый эффект установки ловушки для вашего исполняемого файла не может быть достигнут.

Итак, чтобы увидеть ваш код в действии, вам нужно будет выполнить одно из следующих действий:

  • запустить его вне Visual Studio
  • запустите его внутри Visual Studio, но через меню «Отладка» -> «Начать без отладки»
  • отключите процесс размещения Visual Studio, см. ниже

Обратите внимание, что вы можете отключить процесс хостинга Visual Studio, но имейте в виду возможные побочные эффекты, цитата:

Когда процесс хостинга отключен, некоторые функции отладки недоступны или их производительность снижается. Для получения дополнительной информации см. Отладка и процесс размещения.

person Steffen Opel    schedule 27.07.2009

Вы можете проверить мой ответ на связанный вопрос здесь. Обратите внимание на разницу в методе RegisterLowLevelHook (вы назвали свой KeyboardHook, чтобы знать, что сравнивать). У меня не было проблем с его использованием даже при отладке из VS. В основном, как заявляли другие, не используйте метод GetExecutingAssembly, а вместо этого используйте то, что я перечислил в другом ответе.

Вот отрывок одной интересующей вас функции:

private IntPtr RegisterLowLevelHook(LowLevelKeyboardProc hook)
{
    IntPtr handle = IntPtr.Zero;

    using (Process currentProcess = Process.GetCurrentProcess())
    using (ProcessModule currentModule = currentProcess.MainModule)
    {
        IntPtr module = Kernel32.GetModuleHandle(currentModule.ModuleName);
        handle = User32.SetWindowsHookEx(HookType.KEYBOARD_LL, hook, module, 0);
    }

    return handle;
}
person Erich Mirabal    schedule 27.07.2009