如何阻止ALT+F4关闭C#控制台应用?已拦截Ctrl+C与Ctrl+Break
拦截C#控制台应用的ALT+F4关闭操作
你已经通过Console.CancelKeyPress搞定了CTRL+C和CTRL+Break的拦截,但ALT+F4是系统向控制台窗口发送WM_CLOSE消息触发的关闭,这个没法用.NET自带的Console类处理,得借助Windows API拦截窗口消息来解决。
实现思路
- 调用Windows API获取控制台窗口的句柄
- 替换窗口默认的消息处理逻辑,专门拦截
WM_CLOSE消息 - 在自定义处理逻辑里,忽略
WM_CLOSE以阻止窗口关闭
完整代码示例
using System; using System.Runtime.InteropServices; class Program { // 导入所需Windows API函数 [DllImport("user32.dll")] private static extern IntPtr GetConsoleWindow(); [DllImport("user32.dll")] private static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int nIndex, IntPtr dwNewLong); [DllImport("user32.dll")] private static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam); // 窗口过程索引常量 private const int GWL_WNDPROC = -4; // 窗口关闭消息常量 private const uint WM_CLOSE = 0x0010; // 保存原始窗口过程,用于后续恢复 private static IntPtr _originalWndProc; static void Main(string[] args) { // 拦截CTRL+C和CTRL+Break Console.CancelKeyPress += (sender, e) => e.Cancel = true; // 获取控制台窗口句柄 IntPtr consoleHandle = GetConsoleWindow(); // 替换窗口消息处理函数为自定义逻辑 _originalWndProc = SetWindowLongPtr(consoleHandle, GWL_WNDPROC, Marshal.GetFunctionPointerForDelegate(new WndProcDelegate(CustomWndProc))); Console.WriteLine("控制台已启动,按任意键退出..."); Console.ReadKey(); // 程序退出时恢复原始窗口过程(建议添加,避免遗留影响) SetWindowLongPtr(consoleHandle, GWL_WNDPROC, _originalWndProc); } // 定义窗口过程委托 private delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam); // 自定义窗口消息处理逻辑 private static IntPtr CustomWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { // 拦截WM_CLOSE消息,直接返回0阻止窗口关闭 if (msg == WM_CLOSE) { return IntPtr.Zero; } // 其他消息交给原始窗口过程处理 return CallWindowProc(_originalWndProc, hWnd, msg, wParam, lParam); } }
注意事项
- 该方案依赖Windows API,仅适用于Windows平台的控制台应用
- 恢复原始窗口过程是良好实践,避免程序退出后对控制台环境产生潜在影响
内容的提问来源于stack exchange,提问作者RodyaHjilz
相关产品推荐
相关产品推荐

