#if !NET_2_1
private class WindowsConsole
{
+ public static bool ctrlHandlerAdded = 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 ()
{
{
return GetConsoleOutputCP ();
}
+
+ public static void AddCtrlHandler ()
+ {
+ SetConsoleCtrlHandler (cancelHandler, true);
+ ctrlHandlerAdded = true;
+ }
+
+ public static void RemoveCtrlHandler ()
+ {
+ SetConsoleCtrlHandler (cancelHandler, false);
+ ctrlHandlerAdded = false;
+ }
}
#endif
+
internal static TextWriter stdout;
private static TextWriter stderr;
private static TextReader stdin;
+#if NET_4_5
+ static TextWriter console_stdout;
+ static TextWriter console_stderr;
+ static TextReader console_stdin;
+#endif
+
static Console ()
{
#if NET_2_1
inputEncoding = outputEncoding = Encoding.Default;
}
- stderr = new UnexceptionalStreamWriter (OpenStandardError (0), outputEncoding);
- ((StreamWriter)stderr).AutoFlush = true;
- stderr = TextWriter.Synchronized (stderr, true);
+ SetupStreams (inputEncoding, outputEncoding);
+ }
+ static void SetupStreams (Encoding inputEncoding, Encoding outputEncoding)
+ {
#if !NET_2_1
if (!Environment.IsRunningOnWindows && ConsoleDriver.IsConsole) {
StreamWriter w = new CStreamWriter (OpenStandardOutput (0), outputEncoding);
w.AutoFlush = true;
stdout = TextWriter.Synchronized (w, true);
+
+ w = new CStreamWriter (OpenStandardOutput (0), outputEncoding);
+ w.AutoFlush = true;
+ stderr = TextWriter.Synchronized (w, true);
+
stdin = new CStreamReader (OpenStandardInput (0), inputEncoding);
} else {
#endif
+#if FULL_AOT_RUNTIME
+ Type nslogwriter = Type.GetType ("MonoTouch.Foundation.NSLogWriter, monotouch, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null");
+ stdout = (TextWriter) Activator.CreateInstance (nslogwriter);
+#else
stdout = new UnexceptionalStreamWriter (OpenStandardOutput (0), outputEncoding);
((StreamWriter)stdout).AutoFlush = true;
+#endif
stdout = TextWriter.Synchronized (stdout, true);
+
+#if FULL_AOT_RUNTIME
+ stderr = (TextWriter) Activator.CreateInstance (nslogwriter);
+#else
+ stderr = new UnexceptionalStreamWriter (OpenStandardError (0), outputEncoding);
+ ((StreamWriter)stderr).AutoFlush = true;
+#endif
+ stderr = TextWriter.Synchronized (stderr, true);
+
stdin = new UnexceptionalStreamReader (OpenStandardInput (0), inputEncoding);
stdin = TextReader.Synchronized (stdin);
#if !NET_2_1
}
#endif
+#if NET_4_5
+ console_stderr = stderr;
+ console_stdout = stdout;
+ console_stdin = stdin;
+#endif
+
+#if MONODROID
+ if (LogcatTextWriter.IsRunningOnAndroid ()) {
+ stdout = TextWriter.Synchronized (new LogcatTextWriter ("mono-stdout", stdout));
+ stderr = TextWriter.Synchronized (new LogcatTextWriter ("mono-stderr", stderr));
+ }
+#endif // MONODROID
+
GC.SuppressFinalize (stdout);
GC.SuppressFinalize (stderr);
GC.SuppressFinalize (stdin);
}
}
+#if NET_4_5
+ public static bool IsErrorRedirected {
+ get {
+ return stderr != console_stderr || ConsoleDriver.IsErrorRedirected;
+ }
+ }
+
+ public static bool IsOutputRedirected {
+ get {
+ return stdout != console_stdout || ConsoleDriver.IsOutputRedirected;
+ }
+ }
+
+ public static bool IsInputRedirected {
+ get {
+ return stdin != console_stdin || ConsoleDriver.IsInputRedirected;
+ }
+ }
+#endif
+
private static Stream Open (IntPtr handle, FileAccess access, int bufferSize)
{
-#if NET_2_1 && !MONOTOUCH
+#if MOONLIGHT
if (SecurityManager.SecurityEnabled && !Debugger.IsAttached && Environment.GetEnvironmentVariable ("MOONLIGHT_ENABLE_CONSOLE") == null)
return new NullStream ();
#endif
public static void Write (string format, params object[] arg)
{
- stdout.Write (format, arg);
+ if (arg == null)
+ stdout.Write (format);
+ else
+ stdout.Write (format, arg);
}
public static void Write (char[] buffer, int index, int count)
public static void WriteLine (string format, params object[] arg)
{
- stdout.WriteLine (format, arg);
+ if (arg == null)
+ stdout.WriteLine (format);
+ else
+ stdout.WriteLine (format, arg);
}
public static void WriteLine (char[] buffer, int index, int count)
public static Encoding InputEncoding {
get { return inputEncoding; }
- set { inputEncoding = value; }
+ set {
+ inputEncoding = value;
+ SetupStreams (inputEncoding, outputEncoding);
+ }
}
public static Encoding OutputEncoding {
get { return outputEncoding; }
- set { outputEncoding = value; }
+ set {
+ outputEncoding = value;
+ SetupStreams (inputEncoding, outputEncoding);
+ }
}
public static ConsoleColor BackgroundColor {
ConsoleDriver.Init ();
cancel_event += value;
+
+ if (Environment.IsRunningOnWindows && !WindowsConsole.ctrlHandlerAdded)
+ WindowsConsole.AddCtrlHandler();
}
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.ctrlHandlerAdded)
+ WindowsConsole.RemoveCtrlHandler();
+ }
}
}