使用c#阻止快捷键

发布于 2024-07-28 23:06:58 字数 3058 浏览 4 评论 0原文

我使用下面的代码禁用 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();
        }
    }
}

I am using the below code to disable the Alt+Tab, Alt+Esc, Ctrl+Esc, and Windows Key but somehow it is not working. Please help me rectify it.

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();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

全部不再 2024-08-04 23:06:58

总的来说,代码运行得很好。 您所看到的效果可能源于在 Visual Studio 调试器下运行,这通常意味着您正在运行
Visual Studio 托管进程 (vshost.exe)

这意味着在 KeyboardHook() 函数中调用 System.Reflection.Assembly.GetExecutingAssembly() 返回的是 vshost.exe 而不是可执行文件,因此达到了所需的效果无法为您的可执行文件安装挂钩。

因此,要查看代码的效果,您必须执行以下操作之一:

  • 在 Visual Studio 外部运行它
  • 在 Visual Studio 内部运行它,但通过菜单“调试”->“启动而不调试”
  • 禁用 Visual Studio 托管进程,请参见下文

请注意,您可以禁用 Visual Studio 托管进程,但请注意潜在的副作用,引用:

当托管进程被禁用时,
几个调试功能是
不可用或经验减少
表现。 有关更多信息,请参阅
调试和托管过程

The code in general is working just fine. The effect you are witnessing likely stems from running under the Visual Studio debugger, which usually implies you are running within the
Visual Studio Hosting Process (vshost.exe).

This means that the call to System.Reflection.Assembly.GetExecutingAssembly() within your KeyboardHook() function is returning vshost.exe rather than your executable, consequently the desired effect of installing a hook for your executable can not be achieved.

So to see your code in effect you'll have to do one of the following:

  • run it outside of Visual Studio
  • run it inside Visual Studio, but via menu 'Debug'->'Start without Debugging'
  • disable the Visual Studio Hosting Process, see below

Note that you could disable the Visual Studio Hosting Process, but please be aware of the potential side effects, citation:

When the hosting process is disabled,
several debugging features are
unavailable or experience decreased
performance. For more information, see
Debugging and the Hosting Process.

不气馁 2024-08-04 23:06:58

您可以在此处查看我对相关问题的回答。
请注意 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;
}

You can check out my answer to a related question over here.
Notice the difference in the RegisterLowLevelHook method (you called yours KeyboardHook so you know what to compare). I've not had any problems using this even when debugging from VS.
Basically, as others have stated, don't use the GetExecutingAssembly method but instead what I have listed in the other answer.

Here is the excerpt for the one function of interest to you:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文