colorful

zc qq:1337220912

 

SetConsoleCtrlHandler

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


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

CTRL_CLOSE_EVENT 这些都是在C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\Include\WinCon.h中定义的,c或者c++调用包含这个头文件就可以。

return true的时候关闭的时候会产生应用程序无法关闭的错误,不知道什么原因。return false则不会。根据msdn上的方法说明 If the function handles the control signal, it should return TRUE. If it returns FALSE, the next handler function in the list of handlers for this process is used. 按照这个解释,返回true也不应该出现应用程序无法关闭的错误,不知道是什么原因。

posted on 2012-04-24 22:44 多彩人生 阅读(1155) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

统计

常用链接

留言簿(3)

随笔分类

随笔档案

搜索

最新评论

阅读排行榜

评论排行榜