Classe de gestion Hook du clavier de .NET, utilisée pour désactiver la saisie et la commutation au clavier

1. Classe d'aide MyHook

 Ce type nécessite la programmation de clés blindées désignées, ce qui présente une faible flexibilité.

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

2. Classe d'aide 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);
        }
    }
}

3. Utiliser dans 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()));
        }
    }
}

4. Autres catégories

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

おすすめ

転載: blog.csdn.net/weixin_50478033/article/details/133272524