zoukankan      html  css  js  c++  java
  • 截获控制台程序关闭事件(SetConsoleCtrlHandler)

        最近控制台程序中需要捕获控制台关闭事件,在用户关闭的时候进行某些操作,找了一大圈发现了一个方法,通过调用WIN32 API SetConsoleCtrlHandler方法来实现,具体代码如下:

     1 using System;
     2 using System.Windows.Forms;
     3 using System.Diagnostics;
     4 using System.Runtime.InteropServices;
     5 
     6 namespace ConsoleColsed
     7 {
     8   public delegate bool ConsoleCtrlDelegate(int ctrlType);
     9   class Program
    10   {
    11     [DllImport("kernel32.dll")]
    12     private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
    13     //当用户关闭Console时,系统会发送次消息
    14     private const int CTRL_CLOSE_EVENT = 2;
    15     //Ctrl+C,系统会发送次消息
    16     private const int CTRL_C_EVENT = 0;
    17     //Ctrl+break,系统会发送次消息
    18     private const int CTRL_BREAK_EVENT = 1;
    19     //用户退出(注销),系统会发送次消息
    20     private const int CTRL_LOGOFF_EVENT = 5;
    21     //系统关闭,系统会发送次消息
    22     private const int CTRL_SHUTDOWN_EVENT = 6;
    23 
    24     static void Main(string[] args)
    25     {
    26        Program cls = new Program();
    27        
    28     }
    29     public Program()
    30     {
    31       ConsoleCtrlDelegate consoleDelegete = new  ConsoleCtrlDelegate(HandlerRoutine);
    32 
    33       bool bRet = SetConsoleCtrlHandler(consoleDelegete, true);
    34       if (bRet == false) //安装事件处理失败
    35       {
    36          Debug.WriteLine("error");
    37       }
    38       else
    39       {
    40          Console.WriteLine("ok");
    41         Console.Read();
    42       }
    43     }
    44 
    45     private static bool HandlerRoutine(int ctrlType)
    46     {
    47       switch(ctrlType)
    48       {
    49         case CTRL_C_EVENT:// Ctrl+C 事件
    50           Console.WriteLine("-- CTRL_C_EVENT --");
    51         break;
    52         case CTRL_BREAK_EVENT:
    53           Console.WriteLine("-- CTRL_BREAK_EVENT --");
    54         break;
    55         case CTRL_CLOSE_EVENT://用户点 X 关闭事件
    56           Console.WriteLine("-- CTRL_CLOSE_EVENT --");
    57         break;
    58         case CTRL_LOGOFF_EVENT:
    59         break;
    60         case CTRL_SHUTDOWN_EVENT://系统关闭事件
    61         break;
    62       }
    63     //return true;//表示阻止响应系统对该程序的操作
    64     return false;//忽略处理,让系统进行默认操作
    65     }
    66   }
    67 }   

        不过这个方法我在运用的时候遇到了这样的一个问题:对“::Invoke”类型的已垃圾回收委托进行了回调。这可能会导致应用程序崩溃、损坏和数据丢失。即使将项目 属性-》生成-》忽略不安全代码  这个选项打勾,仍然出现这个错误,除非用Release模式编译运行。Debug模式或者直接运行EXE文件都会报错,在网上查找了一圈找到一个解决方法,那就是先声明一个回调委托的成员变量,这样可以防止被垃圾回收。

  • 相关阅读:
    metadata的使用以及简单的orm模式
    python的cache修饰器
    聊天服务的设计随想
    cherrypy入门
    用python做分布式定时器
    cherrypy & gevent patch
    Python Tornado简单的http request
    连接池的一些感悟
    企业系统架构评估标准
    Nginx与python web服务配置(Uwsgi& FastCGI)
  • 原文地址:https://www.cnblogs.com/theblueberry/p/4315309.html
Copyright © 2011-2022 走看看