SetConsoleCtrlHandler 函式
從呼叫程序的處理常式函式清單中新增或移除應用程式定義的 HandlerRoutine 函式。
如果未指定處理常式函式,該函式就會設定可繼承的屬性,以決定呼叫程序是否會忽略 CTRL+C 訊號。
語法
BOOL WINAPI SetConsoleCtrlHandler(
_In_opt_ PHANDLER_ROUTINE HandlerRoutine,
_In_ BOOL Add
);
參數
HandlerRoutine [in, optional]
指標,指示要加入或移除應用程式定義的 HandlerRoutine 函式。 此參數可以是 Null。
新增 [in]
如果此參數是 TRUE,則會加入處理常式;如果是 FALSE,則會移除處理常式。
如果 HandlerRoutine 參數是 Null,TRUE 值就會使呼叫程序忽略 CTRL+C 的輸入,而 FALSE 值則會還原 CTRL+C 輸入的正常處理程序。 忽略或處理 CTRL+C 的此屬性會由子程序繼承。
傳回值
如果函式成功,則傳回非零的值。
如果此函式失敗,則傳回值為零。 若要取得擴充的錯誤資訊,請呼叫 GetLastError。
備註
此函式會針對主控台應用程式和服務提供類似的通知, WM_QUERYENDSESSION 提供訊息幫浦的圖形化應用程式。 您也可以從圖形化應用程式使用此函式,但無法保證會在來自 WM_QUERYENDSESSION的通知之前到達。
每個主控台程序都會自備應用程式定義的 HandlerRoutine清單,可處理 CTRL+C 和 CTRL+BREAK 函式。 當使用者關閉主控台、登出或關閉系統時,處理常式函式也會處理系統所產生的訊號。 一開始,每個程序的處理常式清單只會包含預設的處理常式函式,該函式會呼叫 ExitProcess 函式。 主控台程序會藉由呼叫 SetConsoleCtrlHandler 函式來新增或移除其他處理常式函式,而這不會影響其他程序的處理常式函式清單。 主控台程序會在收到任何控制訊號時,依據「最後註冊的先呼叫」原則來呼叫其處理常式函式,直到其中一個處理常式傳回 TRUE
為止。 如果沒有任何處理常式傳回 TRUE
,則會呼叫預設的處理常式。
呼叫 AttachConsole、AllocConsole 或 FreeConsole 會將客戶端進程中的控制處理程式數據表重設為其初始狀態。 附加的主控台工作階段變更時,必須再次註冊處理程式。
針對主控台進程,CTRL C 和 CTRL++BREAK 按鍵組合通常被視為訊號(CTRL_C_EVENT和CTRL_BREAK_EVENT)。 當具有鍵盤焦點的主控台視窗收到 CTRL+C 或 CTRL+BREAK 時,訊號通常會傳遞至所有共用該主控台的程序。
CTRL+BREAK 一律會被視為訊號,但是典型的 CTRL+C 行為可透過三種方式來變更,以防止呼叫處理常式函式:
- SetConsoleMode 函式可以停用主控台輸入緩衝區的ENABLE_PROCESSED_INPUT模式,因此 CTRL+C 會回報為鍵盤輸入,而不是做為訊號。
- 使用 Null 和 TRUE 引數呼叫 SetConsoleCtrlHandler會使呼叫程序忽略 CTRL+C 訊號。 此屬性會由子程序繼承,但是可由任何程序啟用或停用,而不會影響現有的程序。
- 如果主控台進程正在偵錯且 CTRL+C 訊號尚未停用,系統會產生DBG_CONTROL_C例外狀況。 此例外狀況的引發只會有益於偵錯工具,應用程式不應使用例外狀況處理常式來處理此狀況。 如果偵錯工具處理了此例外狀況,應用程式將不會注意到 CTRL+C,但會有一個例外:可警告的等待會終止。 如果偵錯工具傳遞未處理的例外狀況,則 CTRL+C 會傳遞至主控台程序並視為訊號,如先前所述。
主控台程序可以使用 GenerateConsoleCtrlEvent 函式來將 CTRL+C 或 CTRL+BREAK 訊號傳送到主控台程序群組。
當使用者關閉主控台、註銷或關閉系統時,系統會產生 CTRL_CLOSE_EVENT、 CTRL_LOGOFF_EVENT和 CTRL_SHUTDOWN_EVENT 訊號,讓進程有機會在終止之前清除。 在處理上述三個訊號中的任何一個時,主控台函式或任何呼叫主控台函式的任何 C 執行階段函式可能無法可靠地運作。 這可能是因為執行程序訊號處理常式之前,已經呼叫部分或所有內部主控台清理常式。
Windows 7、Windows 8、Windows 8.1 和 Windows 10:
如果主控台應用程式載入 gdi32.dll 或 user32.dll 連結庫,當您呼叫 SetConsoleCtrlHandler 時所指定的 HandlerRoutine 函式不會針對CTRL_LOGOFF_EVENT和CTRL_SHUTDOWN_EVENT事件呼叫。 作業系統會將載入 gdi32.dll 或 user32.dll 的程序辨識為 Windows 應用程式,而非主控台應用程式。 如果主控台應用程式不會直接呼叫 gdi32.dll 或 user32.dll 中的函式,也會發生這種行為,但呼叫 Shell 函式之類的函式反而會呼叫 gdi32.dll 或 user32.dll 中的函式。
若要在使用者註銷或裝置在這些情況下關閉時接收事件,請在主控台應用程式中建立隱藏的視窗,然後處理隱藏視窗所接收的WM_QUERYENDSESSION和WM_ENDSESSION視窗訊息。 您可以藉由呼叫 CreateWindowEx 方法,並將 dwExStyle 參數設定為 0,來建立隱藏視窗。 以下是連結的基本處理程式範例所包含的範例。
範例
如需範例,請參閱註冊控制處理常式函式。
需求
最低支援的用戶端 | Windows 2000 Professional [僅限傳統型應用程式] |
最低支援的伺服器 | Windows 2000 Server [僅限傳統型應用程式] |
頁首 | ConsoleApi.h (透過 WinCon.h,包括 Windows.h) |
程式庫 | Kernel32.lib |
DLL | Kernel32.dll |
Unicode 和 ANSI 名稱 |