Created
November 8, 2010 15:16
-
-
Save imphasing/667795 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/mcs/class/corlib/System/Console.cs b/mcs/class/corlib/System/Console.cs | |
index ea9365e..65b56ca 100644 | |
--- a/mcs/class/corlib/System/Console.cs | |
+++ b/mcs/class/corlib/System/Console.cs | |
@@ -44,11 +44,26 @@ namespace System | |
#if !NET_2_1 | |
private class WindowsConsole | |
{ | |
+ public static bool ctrlHandlerHooked = false; | |
+ private delegate bool WindowsCancelHandler (int keyCode); | |
+ private static WindowsCancelHandler cancelHandler = new WindowsCancelHandler (DoWindowsConsoleCancelEvent); | |
+ | |
[DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] | |
private static extern int GetConsoleCP (); | |
[DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] | |
private static extern int GetConsoleOutputCP (); | |
+ [DllImport ("kernel32.dll", CharSet=CharSet.Auto, ExactSpelling=true)] | |
+ private static extern bool SetConsoleCtrlHandler (WindowsCancelHandler handler, bool addHandler); | |
+ | |
+ // Only call the event handler if Control-C was pressed (code == 0), nothing else | |
+ private static bool DoWindowsConsoleCancelEvent (int keyCode) | |
+ { | |
+ if (keyCode == 0) | |
+ DoConsoleCancelEvent (); | |
+ return keyCode == 0; | |
+ } | |
+ | |
[MethodImpl (MethodImplOptions.NoInlining)] | |
public static int GetInputCodePage () | |
{ | |
@@ -60,6 +75,18 @@ namespace System | |
{ | |
return GetConsoleOutputCP (); | |
} | |
+ | |
+ public static void AddCtrlHook () | |
+ { | |
+ SetConsoleCtrlHandler (cancelHandler, true); | |
+ ctrlHandlerHooked = true; | |
+ } | |
+ | |
+ public static void RemoveCtrlHook () | |
+ { | |
+ SetConsoleCtrlHandler (cancelHandler, false); | |
+ ctrlHandlerHooked = false; | |
+ } | |
} | |
#endif | |
internal static TextWriter stdout; | |
@@ -676,12 +703,22 @@ namespace System | |
ConsoleDriver.Init (); | |
cancel_event += value; | |
+ | |
+ if (Environment.IsRunningOnWindows && !WindowsConsole.ctrlHandlerHooked) | |
+ WindowsConsole.AddCtrlHook(); | |
} | |
remove { | |
if (ConsoleDriver.Initialized == false) | |
ConsoleDriver.Init (); | |
cancel_event -= value; | |
+ | |
+ if (cancel_event == null && Environment.IsRunningOnWindows) | |
+ { | |
+ // Need to remove our hook if there's nothing left in the event | |
+ if (WindowsConsole.ctrlHandlerHooked) | |
+ WindowsConsole.RemoveCtrlHook(); | |
+ } | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment