.NET的键盘Hook管理类,用于禁用键盘输入和切换

一、MyHook帮助类

此类需要编写指定屏蔽的按键,灵活性差。

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Windows.Forms;
using Microsoft.Win32;

namespace MyHookClass
{
    /// <summary>
    /// 类一
    /// </summary>
    public class MyHook
    {
        //消息函数的委托
        public delegate int HookProc(int nCode, int wParam, IntPtr lParam);
        static int hHook = 0;
        public const int WH_KEYBOARD_LL = 13;//底层键盘钩子
        static HookProc KeyBoardHookProcedure;

        //按键信息结构
        [StructLayout(LayoutKind.Sequential)]

        public class KeyBoardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        //安装钩子
        [DllImport("user32.dll")]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

        //卸载钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        public static extern bool UnhookWindowsHookEx(int idHook);

        //下一个钩挂的函数
        [DllImport("user32.dll")]
        public static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

        //返回当前线程 ID
        [DllImport("kernel32.dll")]
        public static extern int GetCurrentThreadId();

        //得到模块的句柄
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string name);

        //安装钩子
        public static void InsertHook()
        {
            if (hHook == 0)
            {
                KeyBoardHookProcedure = new HookProc(KeyBoardHookProc);
                hHook = SetWindowsHookEx(WH_KEYBOARD_LL,
                          KeyBoardHookProcedure,
                        GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
                if (hHook == 0)
                {
                    UnHook();
                    throw new Exception("设置Hook失败!");
                }
                else
                {
                    RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System", true);
                    if (key == null)//如果该项不存在的话,则创建该项
                        key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System");
                    key.SetValue("DisableTaskMgr", 1, RegistryValueKind.DWord);
                    //key.SetValue("DisableLockWorkstation", 1, RegistryValueKind.DWord);
                    key.Close();
                }
            }
        }

        //卸载钩子
        public static void UnHook()
        {
            bool retKeyboard = true;
            if (hHook != 0)
            {
                retKeyboard = UnhookWindowsHookEx(hHook);
                hHook = 0;
            }
            //if (!retKeyboard) throw new Exception("卸载Hook失败!");
            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System", true);
            if (key != null)
            {
                key.DeleteValue("DisableTaskMgr", false);
                //key.DeleteValue("DisableLockWorkstation", false);
                key.Close();
            }
        }

        //按键消息的处理函数
        public static int KeyBoardHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
                //添加自己的判断语句,如果符合要求的按键,就 return 1; 
                //没有判断直接 return 1;那么就屏蔽所有按键除了ctrl+alt+del
                //屏蔽Ctrl+Esc
                if (kbh.vkCode == (int)Keys.Delete && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt)      //截获Ctrl+Alt+Delete
                {
                    PubLibrary.WriteErrLog("1.拦截信息:Ctrl+Alt+Delete");
                    return 1;
                }

                if (kbh.vkCode == (int)Keys.Escape)
                {
                    PubLibrary.WriteErrLog("2.拦截信息:Escape");
                    return 1;
                }
                if (kbh.vkCode == 91) // 截获左win(开始菜单键) 
                {
                    PubLibrary.WriteErrLog("3.拦截信息:截获左win");
                    return 1;
                }

                if (kbh.vkCode == 92)// 截获右win 
                {
                    PubLibrary.WriteErrLog("4.拦截信息:截获右win");
                    return 1;
                }

                //if (kbh.vkCode == (int)Keys.L)
                //{
                //    PubLibrary.WriteErrLog("5.拦截信息:L");
                //    return 1;
                //}

                if (kbh.vkCode == (int)Keys.Alt)
                {
                    PubLibrary.WriteErrLog("6.拦截信息:Alt");
                    return 1;
                }
                if ((int)Control.ModifierKeys == (int)Keys.Alt) //截获alt
                {
                    PubLibrary.WriteErrLog("7.拦截信息:Alt");
                    return 1;
                }

                if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control) //截获Ctrl+Esc 
                {
                    PubLibrary.WriteErrLog("8.拦截信息:Ctrl+Esc");
                    return 1;
                }

                if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Alt) //截获Alt+Esc 
                {
                    PubLibrary.WriteErrLog("9.拦截信息:Alt+Esc");
                    return 1;
                }

                if (kbh.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt) //截获alt+f4 
                {
                    PubLibrary.WriteErrLog("10.拦截信息:F4+Alt");
                    return 1;
                }

                if (kbh.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt) //截获alt+tab
                {
                    PubLibrary.WriteErrLog("10.拦截信息:alt+tab");
                    return 1;
                }

                if (kbh.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift) //截获Ctrl+Shift+Esc
                {
                    PubLibrary.WriteErrLog("11.拦截信息:Ctrl+Shift+Esc");
                    return 1;
                }

                if (kbh.vkCode == (int)Keys.Space && (int)Control.ModifierKeys == (int)Keys.Alt) //截获alt+空格 
                {
                    PubLibrary.WriteErrLog("12.拦截信息:alt+空格");
                    return 1;
                }

                if (kbh.vkCode == 241) //截获F1 
                {
                    PubLibrary.WriteErrLog("13.拦截信息:F1");
                    return 1;
                }

                if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete)      //截获Ctrl+Alt+Delete 
                {
                    PubLibrary.WriteErrLog("14.拦截信息:Ctrl+Alt+Delete");
                    return 1;
                }

                if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Shift) //截获Ctrl+Shift 
                {
                    PubLibrary.WriteErrLog("15.拦截信息:Ctrl+Shift");
                    return 1;
                }

                if (kbh.vkCode == (int)Keys.Space && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt) //截获Ctrl+Alt+空格 
                {
                    PubLibrary.WriteErrLog("16.拦截信息:Ctrl+Alt+空格");
                    return 1;
                }
            }

            return CallNextHookEx(hHook, nCode, wParam, lParam);
        }
    }
}

二、KeyboardHookLib帮助类

using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using Microsoft.Win32;

namespace VendorSoftwareReleaseLW.Class
{
    /// <summary>
    /// 键盘Hook管理类
    /// </summary>
    public class KeyboardHookLib
    {
        private const int WH_KEYBOARD_LL = 13; //键盘

        //键盘处理事件委托 ,当捕获键盘输入时调用定义该委托的方法.
        private delegate int HookHandle(int nCode, int wParam, IntPtr lParam);

        //客户端键盘处理事件
        public delegate void ProcessKeyHandle(HookStruct param, out bool handle);

        //接收SetWindowsHookEx返回值
        private static int _hHookValue = 0;

        //勾子程序处理事件
        private HookHandle _KeyBoardHookProcedure;

        //Hook结构
        [StructLayout(LayoutKind.Sequential)]
        public class HookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }

        //设置钩子
        [DllImport("user32.dll")]
        private static extern int SetWindowsHookEx(int idHook, HookHandle lpfn, IntPtr hInstance, int threadId);

        //取消钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern bool UnhookWindowsHookEx(int idHook);

        //调用下一个钩子
        [DllImport("user32.dll")]
        private static extern int CallNextHookEx(int idHook, int nCode, int wParam, IntPtr lParam);

        //获取当前线程ID
        [DllImport("kernel32.dll")]
        private static extern int GetCurrentThreadId();

        //Gets the main module for the associated process.
        [DllImport("kernel32.dll")]
        private static extern IntPtr GetModuleHandle(string name);

        private IntPtr _hookWindowPtr = IntPtr.Zero;

        //构造器
        public KeyboardHookLib() { }

        //外部调用的键盘处理事件
        private static ProcessKeyHandle _clientMethod = null;

        /// <summary>
        /// 安装勾子
        /// </summary>
        /// <param name="hookProcess">外部调用的键盘处理事件</param>
        public void InstallHook(ProcessKeyHandle clientMethod)
        {
            _clientMethod = clientMethod;

            // 安装键盘钩子
            if (_hHookValue == 0)
            {
                _KeyBoardHookProcedure = new HookHandle(OnHookProc);

                _hookWindowPtr = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);

                //************************************ 
                //键盘线程钩子 
                //SetWindowsHookEx( 2,KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId()); //GetCurrentThreadId()为要监视的线程ID,你完全可以自己写个方法获取QQ的线程哦 
                //键盘全局钩子,需要引用空间(using System.Reflection;) 
                //SetWindowsHookEx( 13,KeyboardHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0); 
                // 
                //关于SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId)函数将钩子加入到钩子链表中,说明一下四个参数: 
                //idHook 钩子类型,即确定钩子监听何种消息,上面的代码中设为2,即监听键盘消息并且是线程钩子,如果是全局钩子监听键盘消息应设为13, 
                //线程钩子监听鼠标消息设为7,全局钩子监听鼠标消息设为14。 
                // 
                //lpfn 钩子子程的地址指针。如果dwThreadId参数为0 或是一个由别的进程创建的线程的标识,lpfn必须指向DLL中的钩子子程。 除此以外,lpfn可 
                //以指向当前进程的一段钩子子程代码。钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数。 
                // 
                //hInstance应用程序实例的句柄。标识包含lpfn所指的子程的DLL。如果threadId 标识当前进程创建的一个线程,而且子程代码位于当前 
                //进程,hInstance必须为NULL。可以很简单的设定其为本应用程序的实例句柄。 
                // 
                //threadedId 与安装的钩子子程相关联的线程的标识符。如果为0,钩子子程与所有的线程关联,即为全局钩子。 
                //************************************ 

                _hHookValue = SetWindowsHookEx(
                WH_KEYBOARD_LL,
                _KeyBoardHookProcedure,
                _hookWindowPtr,
                0);

                //如果设置钩子失败.
                if (_hHookValue == 0)
                {

                    UninstallHook();
                }
                else
                {
                    RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System", true);
                    if (key == null)//如果该项不存在的话,则创建该项
                        key = Registry.CurrentUser.CreateSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System");
                    key.SetValue("DisableTaskMgr", 1, RegistryValueKind.DWord);
                    //key.SetValue("DisableLockWorkstation", 1, RegistryValueKind.DWord);
                    key.Close();
                }

            }
        }

        //取消钩子事件
        public void UninstallHook()
        {
            if (_hHookValue != 0)
            {
                bool ret = UnhookWindowsHookEx(_hHookValue);
                if (ret) _hHookValue = 0;
            }

            RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Policies\System", true);
            if (key != null)
            {
                key.DeleteValue("DisableTaskMgr", false);
                //key.DeleteValue("DisableLockWorkstation", false);
                key.Close();
            }
        }

        //钩子事件内部调用,调用_clientMethod方法转发到客户端应用。
        private static int OnHookProc(int nCode, int wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                //转换结构
                HookStruct hookStruct = (HookStruct)Marshal.PtrToStructure(lParam, typeof(HookStruct));

                if (_clientMethod != null)
                {
                    bool handle = false;
                    //调用客户提供的事件处理程序。
                    _clientMethod(hookStruct, out handle);
                    if (handle) return 1; //1:表示拦截键盘,return 退出
                }
            }
            return CallNextHookEx(_hHookValue, nCode, wParam, lParam);
        }
    }
}

三、在WinForm中的使用

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using MyHookClass;
using KeyboardHookLibClass;

namespace TestForm
{
    public partial class LoginForm : Form
    {
        DateTime _dtNow;

        [DllImport("user32.dll")]
        private static extern IntPtr GetForegroundWindow();
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);
        [DllImport("user32.dll")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int uFlags);
        [DllImport("user32.dll")]
        public static extern bool IsWindowVisible(IntPtr hWnd);

        //勾子管理类
        private KeyboardHookLib _keyboardHook = null;

        public delegate void ForegroundWin();

        private void LoginForm_Load(object sender, EventArgs e)
        {
            SetHook();

            Thread threadForeground = new Thread(ShowWindowAsync);
            //threadForeground.IsBackground = true;
            threadForeground.Start();
        }

        private void txt_KeyDown(object sender, KeyEventArgs e)
        {
            _dtNow = DateTime.Now;
        }

        private void txt_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode != Keys.Enter)
            {
                DateTime dtTemp = DateTime.Now;
                TimeSpan ts = dtTemp.Subtract(_dtNow);
                if (ts.Milliseconds > 65)
                {
                    //setTool("错误:禁止手工输入!", "N");
                    txt.Text = "";//清空
                }
            }
        }

        private void txtID_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == 13)
            {
                //做些操作
                ClearHook();
            }
        }

        public static void SetWindowPos(IntPtr hWnd)
        {
            //0x0010为不激活窗口,这个比较关键
            SetWindowPos(hWnd, -1, 0, 0, 0, 0, 0x0001 | 0x0002 | 0x0010);// 0x001 | 0x002 | 0x0010| 0x040
            
        }

        private void ShowWindowAsync()
        {
            while (true)
            {
                //高版本的这里可以直接使用Action,更简化一些
                //ForegroundWin d = new ForegroundWin(action);
                //this.Invoke(d);
                Action a = new Action(() => { action(); });
                Thread.Sleep(100);//这个时间间隔,用户基本感觉不出有切换窗体
            }
        }

        void action()
        {
            IntPtr hWnd = this.Handle;
            if (hWnd != IntPtr.Zero || GetForegroundWindow() != hWnd)
            {
                //选中当前的句柄窗口
                SetWindowPos(hWnd);
                //SendKeys.SendWait(" ");
            }
        }

        private void ClearHook() 
        {
            //取消勾子
            if (_keyboardHook != null) _keyboardHook.UninstallHook();

            //MyHook.UnHook();

            //ProcessMgr.ResumeWinlogon();
        }

        private void SetHook() 
        {
            //安装勾子
            _keyboardHook = new KeyboardHookLib();
            _keyboardHook.InstallHook(this.OnKeyPress);
            //MyHook.InsertHook();

            //ProcessMgr.SuspendWinlogon();
        }

        /// <summary>
        /// 客户端键盘捕捉事件.
        /// </summary>
        /// <param name="hookStruct">由Hook程序发送的按键信息</param>
        /// <param name="handle">是否拦截</param>
        public void OnKeyPress(KeyboardHookLib.HookStruct hookStruct, out bool handle)
        {
            handle = false; //预设不拦截任何键

            if (hookStruct.vkCode == 91) // 截获左win(开始菜单键)
            {
                handle = true;
            }

            if (hookStruct.vkCode == 92)// 截获右win
            {
                handle = true;
            }

            if ((int)Control.ModifierKeys == (int)Keys.Alt) //截获alt
            {
                handle = true;
            }

            //截获Ctrl+Esc
            if (hookStruct.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Control)
            {
                handle = true;
            }

            //截获alt+f4
            if (hookStruct.vkCode == (int)Keys.F4 && (int)Control.ModifierKeys == (int)Keys.Alt)
            {
                handle = true;
            }

            //截获alt+tab
            if (hookStruct.vkCode == (int)Keys.Tab && (int)Control.ModifierKeys == (int)Keys.Alt)
            {
                handle = true;
            }

            //截获alt+tab
            if (hookStruct.vkCode == (int)Keys.Escape && (int)Control.ModifierKeys == (int)Keys.Alt)
            {
                handle = true;
            }

            //截获F1
            if (hookStruct.vkCode == (int)Keys.F1)
            {
                handle = true;
            }

            //截获Ctrl+Alt+Delete
            if ((int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt + (int)Keys.Delete)
            {
                handle = true;
            }

            //如果键A~Z
            if (hookStruct.vkCode >= (int)Keys.A && hookStruct.vkCode <= (int)Keys.Z)
            {
                //挡掉B键
                if (hookStruct.vkCode == (int)Keys.B)
                    hookStruct.vkCode = (int)Keys.None; //设键为0

                handle = true;
            }

            Keys key = (Keys)hookStruct.vkCode;
            PubLibrary.WriteErrLog("你按下:" + (key == Keys.None ? "" : key.ToString()));
        }
    }
}

四、其他类

using System;
using System.Runtime.InteropServices;

namespace ShareToolClass
{
    public class ShareTool : IDisposable
    {
        [DllImport("advapi32.dll", SetLastError = true)]
        static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
            int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

        // closes open handes returned by LogonUser       
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        extern static bool CloseHandle(IntPtr handle);

        [DllImport("Advapi32.DLL")]
        static extern bool ImpersonateLoggedOnUser(IntPtr hToken);

        [DllImport("Advapi32.DLL")]
        static extern bool RevertToSelf();
        const int LOGON32_PROVIDER_DEFAULT = 0;
        const int LOGON32_LOGON_NEWCREDENTIALS = 9;
        const int LOGON32_LOGON_INTERACTIVE = 2;
        private bool disposed;

        public ShareTool(string username, string password, string ip)
        {
            // initialize tokens       
            IntPtr pExistingTokenHandle = new IntPtr(0);
            IntPtr pDuplicateTokenHandle = new IntPtr(0);

            try
            {
                // get handle to token       
                bool bImpersonated = LogonUser(username, ip, password,
                    LOGON32_LOGON_NEWCREDENTIALS, LOGON32_PROVIDER_DEFAULT, ref pExistingTokenHandle);

                if (bImpersonated)
                {
                    if (!ImpersonateLoggedOnUser(pExistingTokenHandle))
                    {
                        int nErrorCode = Marshal.GetLastWin32Error();
                        throw new Exception("ImpersonateLoggedOnUser error;Code=" + nErrorCode);
                    }
                }
                else
                {
                    int nErrorCode = Marshal.GetLastWin32Error();
                    throw new Exception("LogonUser error;Code=" + nErrorCode);
                }
            }
            finally
            {
                // close handle(s)       
                if (pExistingTokenHandle != IntPtr.Zero)
                    CloseHandle(pExistingTokenHandle);
                if (pDuplicateTokenHandle != IntPtr.Zero)
                    CloseHandle(pDuplicateTokenHandle);
            }
        }

        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                RevertToSelf();
                disposed = true;
            }
        }

        public void Dispose()
        {
            Dispose(true);
        }
    }
}

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace ProcessMgrClass
{
    class ProcessMgr
    {
        /// <summary>
        /// The process-specific access rights.
        /// </summary>
        [Flags]
        public enum ProcessAccess : uint
        {
            /// <summary>
            /// Required to terminate a process using TerminateProcess.
            /// </summary>
            Terminate = 0x1,

            /// <summary>
            /// Required to create a thread.
            /// </summary>
            CreateThread = 0x2,

            /// <summary>
            /// Undocumented.
            /// </summary>
            SetSessionId = 0x4,

            /// <summary>
            /// Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory).
            /// </summary>
            VmOperation = 0x8,

            /// <summary>
            /// Required to read memory in a process using ReadProcessMemory.
            /// </summary>
            VmRead = 0x10,

            /// <summary>
            /// Required to write to memory in a process using WriteProcessMemory.
            /// </summary>
            VmWrite = 0x20,

            /// <summary>
            /// Required to duplicate a handle using DuplicateHandle.
            /// </summary>
            DupHandle = 0x40,

            /// <summary>
            /// Required to create a process.
            /// </summary>
            CreateProcess = 0x80,

            /// <summary>
            /// Required to set memory limits using SetProcessWorkingSetSize.
            /// </summary>
            SetQuota = 0x100,

            /// <summary>
            /// Required to set certain information about a process, such as its priority class (see SetPriorityClass).
            /// </summary>
            SetInformation = 0x200,

            /// <summary>
            /// Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob).
            /// </summary>
            QueryInformation = 0x400,

            /// <summary>
            /// Undocumented.
            /// </summary>
            SetPort = 0x800,

            /// <summary>
            /// Required to suspend or resume a process.
            /// </summary>
            SuspendResume = 0x800,

            /// <summary>
            /// Required to retrieve certain information about a process (see QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION.
            /// </summary>
            QueryLimitedInformation = 0x1000,

            /// <summary>
            /// Required to wait for the process to terminate using the wait functions.
            /// </summary>
            Synchronize = 0x100000
        }

        [DllImport("ntdll.dll")]
        private static extern uint NtResumeProcess([In] IntPtr processHandle);

        [DllImport("ntdll.dll")]
        private static extern uint NtSuspendProcess([In] IntPtr processHandle);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern IntPtr OpenProcess(
        ProcessAccess desiredAccess,
        bool inheritHandle,
        int processId);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle([In] IntPtr handle);

        public static void SuspendProcess(int processId)
        {
            IntPtr hProc = IntPtr.Zero;
            try
            {
                // Gets the handle to the Process
                hProc = OpenProcess(ProcessAccess.SuspendResume, false, processId);
                if (hProc != IntPtr.Zero)
                    NtSuspendProcess(hProc);
            }
            finally
            {
                // Don't forget to close handle you created.
                if (hProc != IntPtr.Zero)
                    CloseHandle(hProc);
            }
        }

        public static void ResumeProcess(int processId)
        {
            IntPtr hProc = IntPtr.Zero;
            try
            {
                // Gets the handle to the Process
                hProc = OpenProcess(ProcessAccess.SuspendResume, false, processId);
                if (hProc != IntPtr.Zero)
                    NtResumeProcess(hProc);
            }
            finally
            {
                // Don't forget to close handle you created.
                if (hProc != IntPtr.Zero)
                    CloseHandle(hProc);
            }
        }

        public static void SuspendWinlogon()
        {
            Process[] processes = Process.GetProcesses();
            foreach (Process process in processes)
            {
                if (process.ProcessName == "winlogon")
                {
                    SuspendProcess(process.Id);
                }
            }
        }

        public static void ResumeWinlogon()
        {
            Process[] processes = Process.GetProcesses();
            foreach (Process process in processes)
            {
                Console.WriteLine(process.ProcessName);
                if (process.ProcessName == "winlogon")
                {
                    ResumeProcess(process.Id);
                }
            }
        }
    }
}
相关推荐
昔舍2 小时前
C#笔记(3)
笔记·c#
吾与谁归in4 小时前
【C#设计模式(4)——构建者模式(Builder Pattern)】
设计模式·c#·建造者模式
暴走的锅巴4 小时前
由C#委托回调想到的二三事
c#·gc·委托·垃圾回收·资源管理·资源释放·delegate
sukalot5 小时前
windows C#-查询表达式基础(一)
开发语言·c#
我是苏苏5 小时前
C# Main函数中调用异步方法
前端·javascript·c#
Crazy Struggle8 小时前
Visual Studio 快速分析 .NET Dump 文件
.net·visual studio·内存分析·dump 文件
界面开发小八哥9 小时前
界面控件DevExpress WPF中文教程:TreeList视图及创建分配视图
.net·wpf·界面控件·devexpress·ui开发
晨曦_子画9 小时前
用于在 .NET 中构建 Web API 的 FastEndpoints 入门
前端·.net
慧都小妮子9 小时前
Spire.PDF for .NET【页面设置】演示:复制 PDF 文档中的页面
java·pdf·.net
慧都小妮子9 小时前
Spire.PDF for .NET【页面设置】演示:在 PDF 文件中添加图像作为页面背景
前端·pdf·.net·spire.pdf