【转】捕获控制台程序关闭事件-SetConsoleCtrlHandler

原文地址:https://blog.csdn.net/yanggenxiang/article/details/7692957

有时候运行在服务器上的控制台程序,需要记录详细的运行日志,这就需要对程序关闭进行日志记录,以便能根据日志了解程序的运行状况。比如正在运行的程序被人不小心关闭了,导致最终任务没有运行成功,这时日志也没有错误记录,对分析原因造成不便,记录了关闭事件日志后就能了解到这种情况是程序被终止了。这样注意通过消息钩子来实现,通过调用WIN32 API SetConsoleCtrlHandler方法来实现,具体代码如下:

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace TestClose
{
    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)
        {
            Console.WriteLine("开始:");
            Program cls = new Program();
            Console.Read();
        }

        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:
                    //Console.WriteLine("C");
                    break;
                case CTRL_BREAK_EVENT:
                    //Console.WriteLine("BREAK");
                    break;
                case CTRL_CLOSE_EVENT:
                    //Console.WriteLine("CLOSE");
                    break;
                case CTRL_LOGOFF_EVENT:
                    break;
                case CTRL_SHUTDOWN_EVENT:
                    break;
            }
            //return true;//表示阻止响应系统对该程序的操作
            return false;//忽略处理,让系统进行默认操作
        }
    }
}

实战

public Program()
{

        #region --监控关闭按钮--
        public delegate bool ControlCtrlDelegate(int ctrlType);

        [DllImport("kernel32.dll")]
        private static extern bool SetConsoleCtrlHandler(ControlCtrlDelegate handlerRoutine, bool add);

        private static readonly ControlCtrlDelegate CancelHandler = HandlerRoutine;

        /// <summary>
        /// //设置关闭监控时间
        ///  SetConsoleCtrlHandler(CancelHandler, true);
        /// </summary>
        /// <param name="ctrlType"></param>
        /// <returns></returns>
        public static bool HandlerRoutine(int ctrlType)
        {
            switch (ctrlType)
            {
                case 0: //Ctrl+C关闭  
                case 2: //按控制台关闭按钮关闭
                    //关闭处理
                    break;
            }
            return false;
        }
        #endregion

}

 

posted @ 2019-07-17 17:37  花影疏帘  阅读(416)  评论(0)    收藏  举报