SetConsoleCtrlHandler 函式

從呼叫程序的處理常式函式清單中新增或移除應用程式定義的 HandlerRoutine 函式。

如果未指定處理常式函式,該函式就會設定可繼承的屬性,以決定呼叫程序是否會忽略 CTRL+C 訊號。

語法

BOOL WINAPI SetConsoleCtrlHandler(
  _In_opt_ PHANDLER_ROUTINE HandlerRoutine,
  _In_     BOOL             Add
);

參數

HandlerRoutine [in, optional]
指標,指示要加入或移除應用程式定義的 HandlerRoutine 函式。 此參數可以是 Null

新增 [in]
如果此參數是 TRUE,則會加入處理常式;如果是 FALSE,則會移除處理常式。

如果 HandlerRoutine 參數是 NullTRUE 值就會使呼叫程序忽略 CTRL+C 的輸入,而 FALSE 值則會還原 CTRL+C 輸入的正常處理程序。 忽略或處理 CTRL+C 的此屬性會由子程序繼承。

傳回值

如果函式成功,則傳回非零的值。

如果此函式失敗,則傳回值為零。 若要取得擴充的錯誤資訊,請呼叫 GetLastError

備註

此函式會針對主控台應用程式和服務提供類似的通知, WM_QUERYENDSESSION 提供訊息幫浦的圖形化應用程式。 您也可以從圖形化應用程式使用此函式,但無法保證會在來自 WM_QUERYENDSESSION的通知之前到達。

每個主控台程序都會自備應用程式定義的 HandlerRoutine清單,可處理 CTRL+CCTRL+BREAK 函式。 當使用者關閉主控台、登出或關閉系統時,處理常式函式也會處理系統所產生的訊號。 一開始,每個程序的處理常式清單只會包含預設的處理常式函式,該函式會呼叫 ExitProcess 函式。 主控台程序會藉由呼叫 SetConsoleCtrlHandler 函式來新增或移除其他處理常式函式,而這不會影響其他程序的處理常式函式清單。 主控台程序會在收到任何控制訊號時,依據「最後註冊的先呼叫」原則來呼叫其處理常式函式,直到其中一個處理常式傳回 TRUE 為止。 如果沒有任何處理常式傳回 TRUE,則會呼叫預設的處理常式。

呼叫 AttachConsoleAllocConsole 或 FreeConsole 會將客戶端進程中的控制處理程式數據表重設為其初始狀態。 附加的主控台工作階段變更時,必須再次註冊處理程式。

針對主控台進程,CTRL CCTRL++BREAK 按鍵組合通常被視為訊號(CTRL_C_EVENTCTRL_BREAK_EVENT)。 當具有鍵盤焦點的主控台視窗收到 CTRL+CCTRL+BREAK 時,訊號通常會傳遞至所有共用該主控台的程序。

CTRL+BREAK 一律會被視為訊號,但是典型的 CTRL+C 行為可透過三種方式來變更,以防止呼叫處理常式函式:

  • SetConsoleMode 函式可以停用主控台輸入緩衝區的ENABLE_PROCESSED_INPUT模式,因此 CTRL+C 會回報為鍵盤輸入,而不是做為訊號。
  • 使用 NullTRUE 引數呼叫 SetConsoleCtrlHandler會使呼叫程序忽略 CTRL+C 訊號。 此屬性會由子程序繼承,但是可由任何程序啟用或停用,而不會影響現有的程序。
  • 如果主控台進程正在偵錯且 CTRL+C 訊號尚未停用,系統會產生DBG_CONTROL_C例外狀況。 此例外狀況的引發只會有益於偵錯工具,應用程式不應使用例外狀況處理常式來處理此狀況。 如果偵錯工具處理了此例外狀況,應用程式將不會注意到 CTRL+C,但會有一個例外:可警告的等待會終止。 如果偵錯工具傳遞未處理的例外狀況,則 CTRL+C 會傳遞至主控台程序並視為訊號,如先前所述。

主控台程序可以使用 GenerateConsoleCtrlEvent 函式來將 CTRL+CCTRL+BREAK 訊號傳送到主控台程序群組。

當使用者關閉主控台、註銷或關閉系統時,系統會產生 CTRL_CLOSE_EVENTCTRL_LOGOFF_EVENTCTRL_SHUTDOWN_EVENT 訊號,讓進程有機會在終止之前清除。 在處理上述三個訊號中的任何一個時,主控台函式或任何呼叫主控台函式的任何 C 執行階段函式可能無法可靠地運作。 這可能是因為執行程序訊號處理常式之前,已經呼叫部分或所有內部主控台清理常式。

Windows 7、Windows 8、Windows 8.1 和 Windows 10:

如果主控台應用程式載入 gdi32.dll 或 user32.dll 連結庫,當您呼叫 SetConsoleCtrlHandler 時所指定的 HandlerRoutine 函式不會針對CTRL_LOGOFF_EVENTCTRL_SHUTDOWN_EVENT事件呼叫。 作業系統會將載入 gdi32.dll 或 user32.dll 的程序辨識為 Windows 應用程式,而非主控台應用程式。 如果主控台應用程式不會直接呼叫 gdi32.dll 或 user32.dll 中的函式,也會發生這種行為,但呼叫 Shell 函式之類的函式反而會呼叫 gdi32.dll 或 user32.dll 中的函式。

若要在使用者註銷或裝置在這些情況下關閉時接收事件,請在主控台應用程式中建立隱藏的視窗,然後處理隱藏視窗所接收的WM_QUERYENDSESSIONWM_ENDSESSION視窗訊息。 您可以藉由呼叫 CreateWindowEx 方法,並將 dwExStyle 參數設定為 0,來建立隱藏視窗。 以下是連結的基本處理程式範例所包含的範例。

範例

如需範例,請參閱註冊控制處理常式函式

需求

   
最低支援的用戶端 Windows 2000 Professional [僅限傳統型應用程式]
最低支援的伺服器 Windows 2000 Server [僅限傳統型應用程式]
頁首 ConsoleApi.h (透過 WinCon.h,包括 Windows.h)
程式庫 Kernel32.lib
DLL Kernel32.dll
Unicode 和 ANSI 名稱

另請參閱

主控台控制處理常式

主控台函式

ExitProcess

GenerateConsoleCtrlEvent

GetConsoleMode

HandlerRoutine

SetConsoleMode