截获控制台程序关闭事件(SetConsoleCtrlHandler)
2015-03-05 11:19
363 查看
最近控制台程序中需要捕获控制台关闭事件,在用户关闭的时候进行某些操作,找了一大圈发现了一个方法,通过调用WIN32 API SetConsoleCtrlHandler方法来实现,具体代码如下:
不过这个方法我在运用的时候遇到了这样的一个问题:对“::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。即使将项目 属性-》生成-》忽略不安全代码 这个选项打勾,仍然出现这个错误,除非用Release模式编译运行。Debug模式或者直接运行EXE文件都会报错,在网上查找了一圈找到一个解决方法,那就是先声明一个回调委托的成员变量,这样可以防止被垃圾回收。
using System; using System.Windows.Forms; using System.Diagnostics; using System.Runtime.InteropServices; namespace ConsoleColsed { public delegate bool ConsoleCtrlDelegate(int ctrlType); class Program { [DllImport("kernel32.dll")] private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add); //当用户关闭Console时,系统会发送次消息 private const int CTRL_CLOSE_EVENT = 2; //Ctrl+C,系统会发送次消息 private const int CTRL_C_EVENT = 0; //Ctrl+break,系统会发送次消息 private const int CTRL_BREAK_EVENT = 1; //用户退出(注销),系统会发送次消息 private const int CTRL_LOGOFF_EVENT = 5; //系统关闭,系统会发送次消息 private const int CTRL_SHUTDOWN_EVENT = 6; static void Main(string[] args) { Program cls = new Program(); } public Program() { ConsoleCtrlDelegate consoleDelegete = new ConsoleCtrlDelegate(HandlerRoutine); bool bRet = SetConsoleCtrlHandler(consoleDelegete, true); if (bRet == false) //安装事件处理失败 { Debug.WriteLine("error"); } else { Console.WriteLine("ok"); Console.Read(); } } private static bool HandlerRoutine(int ctrlType) { switch(ctrlType) { case CTRL_C_EVENT:// Ctrl+C 事件 Console.WriteLine("-- CTRL_C_EVENT --"); break; case CTRL_BREAK_EVENT: Console.WriteLine("-- CTRL_BREAK_EVENT --"); break; case CTRL_CLOSE_EVENT://用户点 X 关闭事件 Console.WriteLine("-- CTRL_CLOSE_EVENT --"); break; case CTRL_LOGOFF_EVENT: break; case CTRL_SHUTDOWN_EVENT://系统关闭事件 break; } //return true;//表示阻止响应系统对该程序的操作 return false;//忽略处理,让系统进行默认操作 } } }
不过这个方法我在运用的时候遇到了这样的一个问题:对“::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。即使将项目 属性-》生成-》忽略不安全代码 这个选项打勾,仍然出现这个错误,除非用Release模式编译运行。Debug模式或者直接运行EXE文件都会报错,在网上查找了一圈找到一个解决方法,那就是先声明一个回调委托的成员变量,这样可以防止被垃圾回收。
相关文章推荐
- C#注册控件处理程序(SetConsoleCtrlHandler)函数示例 控制台关闭事件改写
- 捕获控制台程序关闭事件(SetConsoleCtrlHandler
- 再谈Delphi关机消息拦截 -- 之控制台程序 SetConsoleCtrlHandler(控制台使用回调函数拦截,比较有意思)
- 再谈Delphi关机消息拦截 -- 之控制台程序 SetConsoleCtrlHandler
- 控制台获取键盘事件--SetConsoleCtrlHandler 处理控制台消息
- SetConsoleCtrlHandler() -- 设置控制台信号处理函数
- SetConsoleCtrlHandler 处理控制台消息
- SetConsoleCtrlHandler 处理控制台消息
- 如何捕捉控制台程序的关闭事件。
- C#控制台程序中处理2个关闭事件的代码实例
- SetConsoleCtrlHandler 处理控制台消息
- SetConsoleCtrlHandler 处理控制台消息
- SetConsoleCtrlHandler 处理控制台消息
- C++控制台程序的关闭事件
- C#控制台程序中处理2个关闭事件的代码实例
- 如何捕捉控制台程序的关闭事件
- SetConsoleCtrlHandler 处理控制台消息
- 如何捕捉控制台程序的关闭事件
- 蛋疼的让C#控制台程序(Console)像窗体(Winform)一样(关闭,托盘图标,事件响应,手动退出等)
- 如何捕捉控制台程序的关闭事件(转)