Skip to content

Instantly share code, notes, and snippets.

@imphasing
Created November 8, 2010 15:16
Show Gist options
  • Save imphasing/667795 to your computer and use it in GitHub Desktop.
Save imphasing/667795 to your computer and use it in GitHub Desktop.
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