添加或刪除應用程式定義的HandlerRoutine從調用進程的處理函數列表功能。
Win32 API
功能:
添加或刪除應用程式定義的HandlerRoutine從調用進程的處理函數列表功能。
函數原型:
BOOL SetConsoleCtrlHandler(PHANDLER_ROUTINE HandlerRoutine, // 回呼函數BOOL Add // 表示添加還是刪除);
傳回值:BOOL類型
參數
參數HandlerRoutine:一個應用程式定義的指標HandlerRoutine 功能要添加或刪除。 這個參數可以是NULL。
參數Add:如果此參數為TRUE,處理常式添加,如果是假的,該處理常式將被刪除。
傳回值:
如果函數失敗,傳回值為0.否則,返回一個非0值。 若想獲得更多錯誤資訊,調用GetLastError函數 。
說白了,就是一個系統調用。
第一個參數是函數指標,就是上面的那個函數。第二個參數是標誌,如果為TRUE那麼就安裝鉤子,如果為FALSE那麼刪除鉤子。
利用Windows API 攔截Console的手動關閉事件的訊息,來實現,下面我給出的是一個完整的案例:
using System;using System.Collections.Generic;using System.Runtime.InteropServices;using System.Text;using System.Threading;/************************************************************************//* CSharp控制台關閉事件改寫 * Powered by:testcs_dn * Blog:http://www.php.cn/ *//************************************************************************/namespace CSharp控制台關閉事件改寫{ /// <summary> /// 控制台關閉事件改寫 /// 這裡展示了Windows API SetConsoleCtrlHandler函數的應用,同時展示了線程計時器的使用; /// Author:testcs_dn /// Date:2015-01-03 /// </summary> class Program { /// <summary> /// 計時器回呼函數,在這裡處理計時時間是否到達的判斷以及要做的事情; /// </summary> /// <param name="obj"></param> public static void workOvertimeTimerCallback(object obj) { DateTime dt = DateTime.Now; if (dt.Hour == 16 && dt.Minute > 0) { Console.WriteLine("ok"); } } //計時器變數 public static System.Threading.Timer workOvertimeTimer = null; //定義處理常式委託 delegate bool ConsoleCtrlDelegate(int dwCtrlType); const int CTRL_CLOSE_EVENT = 2; //匯入SetCtrlHandlerHandler API [DllImport("kernel32.dll")] private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add); static void Main(string[] args) { ConsoleCtrlDelegate newDelegate = new ConsoleCtrlDelegate(HandlerRoutine); if (SetConsoleCtrlHandler(newDelegate, true)) { //初始化計時器 workOvertimeTimer = new System.Threading.Timer(new TimerCallback(workOvertimeTimerCallback), null, 1000, 10000); //這裡執行你自己的任務,我舉例輸出“...”,為了展示長時間的任務,我用了一個死迴圈; //避免輸出太多,使用了Sleep; //注意:Sleep的時間不可太長,否則可能影響Console.ReadKey(),導致不能接收使用者輸入; while (true) { Console.WriteLine("..."); Thread.Sleep(100); } } else { Console.WriteLine("抱歉,API注入失敗,按任意鍵退出!"); Console.ReadKey(); } } /// <summary> /// 處理常式常式,在這裡編寫對指定事件的處理常式代碼 /// </summary> /// <param name="CtrlType"></param> /// <returns></returns> static bool HandlerRoutine(int CtrlType) { switch (CtrlType) { case CTRL_CLOSE_EVENT: //使用者要關閉Console了 Console.WriteLine(); Console.WriteLine("任務還沒有完成,確認要退出嗎?(Y/N)"); ConsoleKeyInfo ki = Console.ReadKey(); return ki.Key == ConsoleKey.Y; default: return true; } } }}