资讯详情

让你的上位机程序独占鳌头

前言

一些学生要求上位机程序启动后可以禁用Win组合,防止操作人员无操作或退出程序。

实现思路

首先,我们需要了解键盘PC工作原理,Windows系统的所有操作都是基于消息机制的,也就是说,我们键盘上的每个按钮通常都是Windows底部发送消息,所以如果你想屏蔽按钮或功能,最直接的方法是拦截消息。

先说实现思路,就是用钩子Hook,我们之前讲扫码枪的时候也讲过这个。

钩子原理

钩子是操作系统信息处理的机制。通过钩子,应用程序可以安装一个钩子回调过程来调用系统,以监控系统中的信息队列。在这些信息到达目标窗口之前处理它们。

钩子特点

  • 钩函数会降低操作系统的性能,因为它会增加系统处理每个信息的成本。

  • 操作系统支持各种类型的钩子,每种类型都提供了其独特的信息处理机制。

  • 对于各种类型的钩子,系统保持独立的钩链,钩链是指向用户提供的回调函数钩过程的链表指针。

  • 尽量避免大量使用钩子。一般在需要时安装,使用后尽快卸载。

代码实现

下面直接贴代码,主要是在键盘钩处理中添加一些需要截获的信息。

publicclassHook:IDisposable { publicdelegateintHookProc(intnCode,intwParam,IntPtrlParam); staticinthHook=0; publicconstintWH_KEYBOARD_LL=13; HookProcKeyBoardHookProcedure; [StructLayout(LayoutKind.Sequential)] publicclassKeyBoardHookStruct { publicintvkCode; publicintscanCode; publicintflags; publicinttime; publicintdwExtraInfo; } [DllImport("user32.dll")] publicstaticexternintSetWindowsHookEx(intidHook,HookProclpfn,IntPtrhInstance,intthreadId); [DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)] publicstaticexternboolUnhookWindowsHookEx(intidHook); [DllImport("user32.dll")] publicstaticexternintCallNextHookEx(intidHook,intnCode,intwParam,IntPtrlParam); [DllImport("kernel32.dll")] publicstaticexternIntPtrGetModuleHandle(stringname); publicvoidStart() { //安装键盘钩 if(hHook==0) { KeyBoardHookProcedure=newHookProc(KeyBoardHookProc); hHook=SetWindowsHookEx(WH_KEYBOARD_LL,KeyBoardHookProcedure,GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName),0); /. if(hHook==0) Close(); else { RegistryKeykey=Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System",true); &nsp;     if (key == null)//如果该项不存在的话,则创建该项
                        key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System");
                    key.SetValue("DisableTaskMgr", 1, RegistryValueKind.DWord);
                    key.Close();
                }
            }
        }
        public void Close()
        {
            bool retKeyboard = true;
            if (hHook != 0)
            {
                retKeyboard = UnhookWindowsHookEx(hHook);
                hHook = 0;
            }
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System", true);
            if (key != null)
            {
                key.DeleteValue("DisableTaskMgr", false);
                key.Close();
            }
        }
        public static int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
                if (kbh.vkCode == 91) // 截获左win(开始菜单键) 
                    return 1;
                if (kbh.vkCode == 92)// 截获右win 
                    return 1;
                if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control) //截获Ctrl+Esc 
                    return 1;
                if (kbh.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt) //截获alt+f4 
                    return 1;
                if (kbh.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt) //截获alt+tab 
                    return 1;
                if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift) //截获Ctrl+Shift+Esc 
                    return 1;
                if (kbh.vkCode == (int)Keys.Space && (int)Control.ModifierKeys == (int)Keys.Alt) //截获alt+空格 
                    return 1;
                if (kbh.vkCode == 241)                  //截获F1 
                    return 1; if (kbh.vkCode == (int)Keys.Control && kbh.vkCode == (int)Keys.Alt && kbh.vkCode == (int)Keys.Delete)
                    return 1;
                if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete)      //截获Ctrl+Alt+Delete 
                    return 1;
                if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift)      //截获Ctrl+Shift 
                    return 1;
            }
            return CallNextHookEx(hHook, nCode, wParam, lParam);
        }

        public void Dispose()
        {
            Close();
        }

    }

钩子使用

使用方法也很简单,在窗体初始化的时候,采用无边框并最大化窗体,然后启动钩子。

        private Hook hook;
        public FrmMain()
        {
            InitializeComponent();

            this.FormBorderStyle = FormBorderStyle.None;
            this.WindowState = FormWindowState.Maximized;
            this.TopMost = true;
            hook = new Hook();
            hook.Start();
            this.FormClosing += new FormClosingEventHandler(FrmMain_FormClosing);
        }

在窗体关闭事件里关闭钩子,钩子使用一定要及时关闭。

        private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)
        {
            hook.Close();
        }

这样运行程序后,如果没有提供关闭程序的入门,似乎就只能重启系统了,大家测试时要注意保存电脑现有程序及文件。

需要相关的资料可以私信我,或者评论区留言

标签: kbh智能压力变送器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

 锐单商城 - 一站式电子元器件采购平台  

 深圳锐单电子有限公司