Følgende kode virker for mig:
#include <windows.h>
#include <stdio.h>
BOOL WINAPI consoleHandler(DWORD signal) {
if (signal == CTRL_C_EVENT)
printf("Ctrl-C handled\n"); // do cleanup
return TRUE;
}
int main()
{
running = TRUE;
if (!SetConsoleCtrlHandler(consoleHandler, TRUE)) {
printf("\nERROR: Could not set control handler");
return 1;
}
while (1) { /* do work */ }
return 0;
}
Ifølge dokumentationen, når handleren (som er erklæret forkert, BTW) modtager en CTRL_CLOSE_EVENT
, CTRL_LOGOFF_EVENT
eller CTRL_SHUTDOWN_EVENT
signal, afsluttes processen, efter at handleren er gået ud. For at gøre, hvad du forsøger, er det meningen, at du skal flytte din oprydningskode ind i selve handleren.
Afhængigt af dine specifikke krav har du en række muligheder. Hvis du blot vil ignorere Ctrl +C du kan ringe til SetConsoleCtrlHandler
bestå NULL
som HandlerRoutine
parameter:
int _tmain(int argc, _TCHAR* argv[])
{
SetConsoleCtrlHandler(NULL, TRUE);
// do work
return 0;
}
Dette fjerner alle signalbehandlere. For at afslutte denne applikation skal du implementere brugerdefineret logik for at bestemme, hvornår du skal lukke ned.
Hvis du vil håndtere Ctrl +C du har to muligheder:Indstil en handler til signalet eller send tastaturinputtet videre til almindelig tastaturhåndtering.
Opsætning af en handler svarer til koden ovenfor, men i stedet for at sende NULL
som handler sørger du for din egen implementering.
#include <windows.h>
#include <stdio.h>
volatile bool isRunnung = true;
BOOL WINAPI HandlerRoutine(_In_ DWORD dwCtrlType) {
switch (dwCtrlType)
{
case CTRL_C_EVENT:
printf("[Ctrl]+C\n");
isRunnung = false;
// Signal is handled - don't pass it on to the next handler
return TRUE;
default:
// Pass signal on to the next handler
return FALSE;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
SetConsoleCtrlHandler(HandlerRoutine, TRUE);
printf("Starting\n");
while ( isRunnung ) {
Sleep(0);
}
printf("Ending\n");
return 0;
}
Outputtet af denne applikation er:
Starting
[Ctrl]+C
Ending
Bemærk, at oprydningskoden udføres, uanset koden inde i hovedkoden while
-løkke. Signalhandlere danner en sammenkædet liste, hvor handlerfunktionerne kaldes på en sidst registrerede, førstkaldte basis, indtil en af handlerne returnerer TRUE
. Hvis ingen af handlerne returnerer TRUE, kaldes standardhandleren. Standardhandleren for en konsol kalder ExitProcess
når du behandler Ctrl +C .
Hvis du vil forhindre enhver forbehandling og håndtere Ctrl +C som almindelig tastaturinput skal du i stedet ændre konsoltilstanden ved at ringe til SetConsoleMode
.
#include <windows.h>
#include <stdio.h>
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwMode = 0x0;
GetConsoleMode( GetStdHandle(STD_INPUT_HANDLE), &dwMode );
// Remove ENABLE_PROCESSED_INPUT flag
dwMode &= ~ENABLE_PROCESSED_INPUT;
SetConsoleMode( GetStdHandle(STD_INPUT_HANDLE), dwMode );
while ( true ) {
// Ctrl+C can be read using ReadConsoleInput, etc.
}
return 0;
}
Når ENABLE_PROCESSED_INPUT
flag er fjernet Ctrl +C behandles ikke længere af systemet og sendes til konsollen som almindelig tastaturinput. Den kan læses ved hjælp af ReadConsoleInput
eller ReadFile
.
Ansvarsfraskrivelse:Ovenstående er blevet testet på Windows 8 64bit, kompileret til 32 og 64 bit, Release- og Debug-konfigurationer.