|
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// ==--==
/*=============================================================================
**
** Class: Console
**
**
** Purpose: This class provides access to the standard input, standard output
** and standard error streams.
**
**
=============================================================================*/
namespace System {
using System;
using System.IO;
using System.Text;
using System.Globalization;
using System.Security;
using System.Security.Permissions;
using Microsoft.Win32;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Runtime.Versioning;
using System.Diagnostics.Contracts;
using System.Diagnostics.CodeAnalysis;
using System.Collections.Generic;
// Provides static fields for console input & output. Use
// Console.In for input from the standard input stream (stdin),
// Console.Out for output to stdout, and Console.Error
// for output to stderr. If any of those console streams are
// redirected from the command line, these streams will be redirected.
// A program can also redirect its own output or input with the
// SetIn, SetOut, and SetError methods.
//
// The distinction between Console.Out & Console.Error is useful
// for programs that redirect output to a file or a pipe. Note that
// stdout & stderr can be output to different files at the same
// time from the DOS command line:
//
// someProgram 1> out 2> err
//
//Contains only static data. Serializable attribute not required.
public static class Console
{
private const int DefaultConsoleBufferSize = 256;
private const short AltVKCode = 0x12;
#if !FEATURE_PAL
private const int NumberLockVKCode = 0x90; // virtual key code
private const int CapsLockVKCode = 0x14;
// Beep range - see MSDN.
private const int MinBeepFrequency = 37;
private const int MaxBeepFrequency = 32767;
// MSDN says console titles can be up to 64 KB in length.
// But I get an exception if I use buffer lengths longer than
// ~24500 Unicode characters. Oh well.
private const int MaxConsoleTitleLength = 24500;
#endif // !FEATURE_PAL
#if !FEATURE_CORECLR
private static readonly UnicodeEncoding StdConUnicodeEncoding = new UnicodeEncoding(false, false);
#endif // !FEATURE_CORECLR
private static volatile TextReader _in;
private static volatile TextWriter _out;
private static volatile TextWriter _error;
private static volatile ConsoleCancelEventHandler _cancelCallbacks;
private static volatile ControlCHooker _hooker;
#if !FEATURE_PAL
// ReadLine & Read can't use this because they need to use ReadFile
// to be able to handle redirected input. We have to accept that
// we will lose repeated keystrokes when someone switches from
// calling ReadKey to calling Read or ReadLine. Those methods should
// ideally flush this cache as well.
[System.Security.SecurityCritical] // auto-generated
private static Win32Native.InputRecord _cachedInputRecord;
// For ResetColor
private static volatile bool _haveReadDefaultColors;
private static volatile byte _defaultColors;
#endif // !FEATURE_PAL
#if FEATURE_CODEPAGES_FILE // if no codepages file then locked into default
private static volatile bool _isOutTextWriterRedirected = false;
private static volatile bool _isErrorTextWriterRedirected = false;
#endif
private static volatile Encoding _inputEncoding = null;
private static volatile Encoding _outputEncoding = null;
#if !FEATURE_CORECLR
private static volatile bool _stdInRedirectQueried = false;
private static volatile bool _stdOutRedirectQueried = false;
private static volatile bool _stdErrRedirectQueried = false;
private static bool _isStdInRedirected;
private static bool _isStdOutRedirected;
private static bool _isStdErrRedirected;
#endif // !FEATURE_CORECLR
// Private object for locking instead of locking on a public type for SQL reliability work.
// Use this for internal synchronization during initialization, wiring up events, or for short, non-blocking OS calls.
private static volatile Object s_InternalSyncObject;
private static Object InternalSyncObject {
get {
Contract.Ensures(Contract.Result<Object>() != null);
if (s_InternalSyncObject == null) {
Object o = new Object();
#pragma warning disable 0420
Interlocked.CompareExchange<Object>(ref s_InternalSyncObject, o, null);
#pragma warning restore 0420
}
return s_InternalSyncObject;
}
}
// Use this for blocking in Console.ReadKey, which needs to protect itself in case multiple threads call it simultaneously.
// Use a ReadKey-specific lock though, to allow other fields to be initialized on this type.
private static volatile Object s_ReadKeySyncObject;
private static Object ReadKeySyncObject
{
get
{
Contract.Ensures(Contract.Result<Object>() != null);
if (s_ReadKeySyncObject == null)
{
Object o = new Object();
#pragma warning disable 0420
Interlocked.CompareExchange<Object>(ref s_ReadKeySyncObject, o, null);
#pragma warning restore 0420
}
return s_ReadKeySyncObject;
}
}
// About reliability: I'm not using SafeHandle here. We don't
// need to close these handles, and we don't allow the user to close
// them so we don't have many of the security problems inherent in
// something like file handles. Additionally, in a host like SQL
// Server, we won't have a console.
private static volatile IntPtr _consoleInputHandle;
private static volatile IntPtr _consoleOutputHandle;
private static IntPtr ConsoleInputHandle {
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
get {
if (_consoleInputHandle == IntPtr.Zero) {
_consoleInputHandle = Win32Native.GetStdHandle(Win32Native.STD_INPUT_HANDLE);
}
return _consoleInputHandle;
}
}
private static IntPtr ConsoleOutputHandle {
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
get {
if (_consoleOutputHandle == IntPtr.Zero) {
_consoleOutputHandle = Win32Native.GetStdHandle(Win32Native.STD_OUTPUT_HANDLE);
}
return _consoleOutputHandle;
}
}
#if !FEATURE_CORECLR
[System.Security.SecuritySafeCritical]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
private static bool IsHandleRedirected(IntPtr ioHandle) {
// Need this to use GetFileType:
SafeFileHandle safeIOHandle = new SafeFileHandle(ioHandle, false);
// If handle is not to a character device, we must be redirected:
int fileType = Win32Native.GetFileType(safeIOHandle);
if ((fileType & Win32Native.FILE_TYPE_CHAR) != Win32Native.FILE_TYPE_CHAR)
return true;
// We are on a char device.
// If GetConsoleMode succeeds, we are NOT redirected.
int mode;
bool success = Win32Native.GetConsoleMode(ioHandle, out mode);
return !success;
}
public static bool IsInputRedirected {
[System.Security.SecuritySafeCritical]
get {
if (_stdInRedirectQueried)
return _isStdInRedirected;
lock (InternalSyncObject) {
if (_stdInRedirectQueried)
return _isStdInRedirected;
_isStdInRedirected = IsHandleRedirected(ConsoleInputHandle);
_stdInRedirectQueried = true;
return _isStdInRedirected;
}
}
} // public static bool IsInputRedirected
public static bool IsOutputRedirected {
[System.Security.SecuritySafeCritical]
get {
if (_stdOutRedirectQueried)
return _isStdOutRedirected;
lock (InternalSyncObject) {
if (_stdOutRedirectQueried)
return _isStdOutRedirected;
_isStdOutRedirected = IsHandleRedirected(ConsoleOutputHandle);
_stdOutRedirectQueried = true;
return _isStdOutRedirected;
}
}
} // public static bool IsOutputRedirected
public static bool IsErrorRedirected {
[System.Security.SecuritySafeCritical]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
get {
if (_stdErrRedirectQueried)
return _isStdErrRedirected;
lock (InternalSyncObject) {
if (_stdErrRedirectQueried)
return _isStdErrRedirected;
IntPtr errHndle = Win32Native.GetStdHandle(Win32Native.STD_ERROR_HANDLE);
_isStdErrRedirected = IsHandleRedirected(errHndle);
_stdErrRedirectQueried = true;
return _isStdErrRedirected;
}
}
} // public static bool IsErrorRedirected
#endif // !FEATURE_CORECLR
public static TextReader In {
[System.Security.SecuritySafeCritical] // auto-generated
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
Contract.Ensures(Contract.Result<TextReader>() != null);
// Because most applications don't use stdin, we can delay
// initialize it slightly better startup performance.
if (_in == null) {
lock(InternalSyncObject) {
if (_in == null) {
// Set up Console.In
Stream s = OpenStandardInput(DefaultConsoleBufferSize);
TextReader tr;
if (s == Stream.Null)
tr = StreamReader.Null;
else {
// Hopefully Encoding.GetEncoding doesn't load as many classes now.
#if FEATURE_CORECLR
Encoding enc = Encoding.UTF8;
#else // FEATURE_CORECLR
Encoding enc = InputEncoding;
#endif // FEATURE_CORECLR
tr = TextReader.Synchronized(new StreamReader(s, enc, false, DefaultConsoleBufferSize, true));
}
System.Threading.Thread.MemoryBarrier();
_in = tr;
}
}
}
return _in;
}
}
public static TextWriter Out {
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
Contract.Ensures(Contract.Result<TextWriter>() != null);
// Hopefully this is inlineable.
if (_out == null)
InitializeStdOutError(true);
return _out;
}
}
public static TextWriter Error {
[HostProtection(UI=true)]
get {
Contract.Ensures(Contract.Result<TextWriter>() != null);
// Hopefully this is inlineable.
if (_error == null)
InitializeStdOutError(false);
return _error;
}
}
// For console apps, the console handles are set to values like 3, 7,
// and 11 OR if you've been created via CreateProcess, possibly -1
// or 0. -1 is definitely invalid, while 0 is probably invalid.
// Also note each handle can independently be invalid or good.
// For Windows apps, the console handles are set to values like 3, 7,
// and 11 but are invalid handles - you may not write to them. However,
// you can still spawn a Windows app via CreateProcess and read stdout
// and stderr.
// So, we always need to check each handle independently for validity
// by trying to write or read to it, unless it is -1.
// We do not do a security check here, under the assumption that this
// cannot create a security hole, but only waste a user's time or
// cause a possible denial of service attack.
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
private static void InitializeStdOutError(bool stdout)
{
// Set up Console.Out or Console.Error.
lock(InternalSyncObject) {
if (stdout && _out != null)
return;
else if (!stdout && _error != null)
return;
TextWriter writer = null;
Stream s;
if (stdout)
s = OpenStandardOutput(DefaultConsoleBufferSize);
else
s = OpenStandardError(DefaultConsoleBufferSize);
if (s == Stream.Null) {
#if _DEBUG
if (CheckOutputDebug())
writer = MakeDebugOutputTextWriter((stdout) ? "Console.Out: " : "Console.Error: ");
else
#endif // _DEBUG
writer = TextWriter.Synchronized(StreamWriter.Null);
}
else {
#if FEATURE_CORECLR
Encoding encoding = Encoding.UTF8;
#else // FEATURE_CORECLR
Encoding encoding = OutputEncoding;
#endif // FEATURE_CORECLR
StreamWriter stdxxx = new StreamWriter(s, encoding, DefaultConsoleBufferSize, true);
stdxxx.HaveWrittenPreamble = true;
stdxxx.AutoFlush = true;
writer = TextWriter.Synchronized(stdxxx);
}
if (stdout)
_out = writer;
else
_error = writer;
Contract.Assert((stdout && _out != null) || (!stdout && _error != null), "Didn't set Console::_out or _error appropriately!");
}
}
// This is ONLY used in debug builds. If you have a registry key set,
// it will redirect Console.Out & Error on console-less applications to
// your debugger's output window.
#if _DEBUG
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
private static bool CheckOutputDebug()
{
#if FEATURE_WIN32_REGISTRY
new System.Security.Permissions.RegistryPermission(RegistryPermissionAccess.Read | RegistryPermissionAccess.Write, "HKEY_LOCAL_MACHINE").Assert();
RegistryKey rk = Registry.LocalMachine;
using (rk = rk.OpenSubKey("Software\\Microsoft\\.NETFramework", false)) {
if (rk != null) {
Object obj = rk.GetValue("ConsoleSpewToDebugger", 0);
if (obj != null && ((int)obj) != 0) {
return true;
}
}
}
return false;
#else // FEATURE_WIN32_REGISTRY
#if FEATURE_PAL && !FEATURE_CORECLR
const int parameterValueLength = 255;
StringBuilder parameterValue = new StringBuilder(parameterValueLength);
bool rc = Win32Native.FetchConfigurationString(true, "ConsoleSpewToDebugger", parameterValue, parameterValueLength);
if (rc) {
if (0 != parameterValue.Length) {
int value = Convert.ToInt32(parameterValue.ToString());
if (0 != value)
return true;
}
}
#endif // FEATURE_PAL && !FEATURE_CORECLR
return false;
#endif // FEATURE_WIN32_REGISTRY
}
#endif // _DEBUG
#if _DEBUG
private static TextWriter MakeDebugOutputTextWriter(String streamLabel)
{
TextWriter output = new __DebugOutputTextWriter(streamLabel);
output.WriteLine("Output redirected to debugger from a bit bucket.");
return TextWriter.Synchronized(output);
}
#endif // _DEBUG
#if !FEATURE_CORECLR
// We cannot simply compare the encoding to Encoding.Unicode bacasue it incorporates BOM
// and we do not care about BOM. Instead, we compare by class, codepage and little-endianess only:
private static bool IsStandardConsoleUnicodeEncoding(Encoding encoding) {
UnicodeEncoding enc = encoding as UnicodeEncoding;
if (null == enc)
return false;
return (StdConUnicodeEncoding.CodePage == enc.CodePage)
&& (StdConUnicodeEncoding.bigEndian == enc.bigEndian);
}
private static bool GetUseFileAPIs(int handleType) {
switch(handleType) {
case Win32Native.STD_INPUT_HANDLE:
return !IsStandardConsoleUnicodeEncoding(InputEncoding) || IsInputRedirected;
case Win32Native.STD_OUTPUT_HANDLE:
return !IsStandardConsoleUnicodeEncoding(OutputEncoding) || IsOutputRedirected;
case Win32Native.STD_ERROR_HANDLE:
return !IsStandardConsoleUnicodeEncoding(OutputEncoding) || IsErrorRedirected;
default:
// This can never happen.
Contract.Assert(false, "Unexpected handleType value (" + handleType + ")");
return true;
}
}
#endif // !FEATURE_CORECLR
// This method is only exposed via methods to get at the console.
// We won't use any security checks here.
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#else
[System.Security.SecuritySafeCritical]
#endif
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
private static Stream GetStandardFile(int stdHandleName, FileAccess access, int bufferSize) {
// We shouldn't close the handle for stdout, etc, or we'll break
// unmanaged code in the process that will print to console.
// We should have a better way of marking this on SafeHandle.
IntPtr handle = Win32Native.GetStdHandle(stdHandleName);
SafeFileHandle sh = new SafeFileHandle(handle, false);
// If someone launches a managed process via CreateProcess, stdout
// stderr, & stdin could independently be set to INVALID_HANDLE_VALUE.
// Additionally they might use 0 as an invalid handle.
if (sh.IsInvalid) {
// Minor perf optimization - get it out of the finalizer queue.
sh.SetHandleAsInvalid();
return Stream.Null;
}
// Check whether we can read or write to this handle.
if (stdHandleName != Win32Native.STD_INPUT_HANDLE && !ConsoleHandleIsWritable(sh)) {
//BCLDebug.ConsoleError("Console::ConsoleHandleIsValid for std handle "+stdHandleName+" failed, setting it to a null stream");
return Stream.Null;
}
#if !FEATURE_CORECLR
bool useFileAPIs = GetUseFileAPIs(stdHandleName);
#else
const bool useFileAPIs = true;
#endif // !FEATURE_CORECLR
//BCLDebug.ConsoleError("Console::GetStandardFile for std handle "+stdHandleName+" succeeded, returning handle number "+handle.ToString());
Stream console = new __ConsoleStream(sh, access, useFileAPIs);
// Do not buffer console streams, or we can get into situations where
// we end up blocking waiting for you to hit enter twice. It was
// redundant.
return console;
}
// Checks whether stdout or stderr are writable. Do NOT pass
// stdin here.
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#else
[System.Security.SecuritySafeCritical]
#endif
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
private static unsafe bool ConsoleHandleIsWritable(SafeFileHandle outErrHandle) {
// Do NOT call this method on stdin!
// Windows apps may have non-null valid looking handle values for
// stdin, stdout and stderr, but they may not be readable or
// writable. Verify this by calling WriteFile in the
// appropriate modes.
// This must handle console-less Windows apps.
int bytesWritten;
byte junkByte = 0x41;
int r = Win32Native.WriteFile(outErrHandle, &junkByte, 0, out bytesWritten, IntPtr.Zero);
// In Win32 apps w/ no console, bResult should be 0 for failure.
return r != 0;
}
public static Encoding InputEncoding {
[System.Security.SecuritySafeCritical] // auto-generated
get {
Contract.Ensures(Contract.Result<Encoding>() != null);
if (null != _inputEncoding)
return _inputEncoding;
lock(InternalSyncObject) {
if (null != _inputEncoding)
return _inputEncoding;
uint cp = Win32Native.GetConsoleCP();
_inputEncoding = Encoding.GetEncoding((int) cp);
return _inputEncoding;
}
}
#if FEATURE_CODEPAGES_FILE // if no codepages file then locked into default
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
if (value == null)
throw new ArgumentNullException("value");
Contract.EndContractBlock();
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
lock(InternalSyncObject) {
if (!IsStandardConsoleUnicodeEncoding(value)) {
uint cp = (uint) value.CodePage;
bool r = Win32Native.SetConsoleCP(cp);
if (!r)
__Error.WinIOError();
}
_inputEncoding = (Encoding) value.Clone();
// We need to reinitialize Console.In in the next call to _in
// This will discard the current StreamReader, potentially
// losing buffered data
_in = null;
}
} // set
#endif // FEATURE_CODEPAGES_FILE
} // public static Encoding InputEncoding
public static Encoding OutputEncoding {
[System.Security.SecuritySafeCritical] // auto-generated
get {
Contract.Ensures(Contract.Result<Encoding>() != null);
if (null != _outputEncoding)
return _outputEncoding;
lock(InternalSyncObject) {
if (null != _outputEncoding)
return _outputEncoding;
uint cp = Win32Native.GetConsoleOutputCP();
_outputEncoding = Encoding.GetEncoding((int) cp);
return _outputEncoding;
}
}
#if FEATURE_CODEPAGES_FILE // if no codepages file then locked into default
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
if (value == null)
throw new ArgumentNullException("value");
Contract.EndContractBlock();
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
lock(InternalSyncObject) {
// Before changing the code page we need to flush the data
// if Out hasn't been redirected. Also, have the next call to
// _out reinitialize the console code page.
if (_out != null && !_isOutTextWriterRedirected) {
_out.Flush();
_out = null;
}
if (_error != null && !_isErrorTextWriterRedirected) {
_error.Flush();
_error = null;
}
if (!IsStandardConsoleUnicodeEncoding(value)) {
uint cp = (uint) value.CodePage;
bool r = Win32Native.SetConsoleOutputCP(cp);
if (!r)
__Error.WinIOError();
}
_outputEncoding = (Encoding) value.Clone();
}
} // set
#endif // FEATURE_CODEPAGES_FILE
} // public static Encoding OutputEncoding
#if !FEATURE_PAL
[HostProtection(UI=true)]
public static void Beep()
{
Beep(800, 200);
}
[System.Security.SecuritySafeCritical] // auto-generated
[HostProtection(UI=true)]
public static void Beep(int frequency, int duration)
{
if (frequency < MinBeepFrequency || frequency > MaxBeepFrequency)
throw new ArgumentOutOfRangeException("frequency", frequency, Environment.GetResourceString("ArgumentOutOfRange_BeepFrequency", MinBeepFrequency, MaxBeepFrequency));
if (duration <= 0)
throw new ArgumentOutOfRangeException("duration", duration, Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
// Note that Beep over Remote Desktop connections does not currently
Contract.EndContractBlock();
// work. Ignore any failures here.
Win32Native.Beep(frequency, duration);
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static void Clear()
{
Win32Native.COORD coordScreen = new Win32Native.COORD();
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi;
bool success;
int conSize;
IntPtr hConsole = ConsoleOutputHandle;
if (hConsole == Win32Native.INVALID_HANDLE_VALUE)
throw new IOException(Environment.GetResourceString("IO.IO_NoConsole"));
// get the number of character cells in the current buffer
// Go through my helper method for fetching a screen buffer info
// to correctly handle default console colors.
csbi = GetBufferInfo();
conSize = csbi.dwSize.X * csbi.dwSize.Y;
// fill the entire screen with blanks
int numCellsWritten = 0;
success = Win32Native.FillConsoleOutputCharacter(hConsole, ' ',
conSize, coordScreen, out numCellsWritten);
if (!success)
__Error.WinIOError();
// now set the buffer's attributes accordingly
numCellsWritten = 0;
success = Win32Native.FillConsoleOutputAttribute(hConsole, csbi.wAttributes,
conSize, coordScreen, out numCellsWritten);
if (!success)
__Error.WinIOError();
// put the cursor at (0, 0)
success = Win32Native.SetConsoleCursorPosition(hConsole, coordScreen);
if (!success)
__Error.WinIOError();
}
[System.Security.SecurityCritical] // auto-generated
private static Win32Native.Color ConsoleColorToColorAttribute(ConsoleColor color, bool isBackground)
{
if ((((int)color) & ~0xf) != 0)
throw new ArgumentException(Environment.GetResourceString("Arg_InvalidConsoleColor"));
Contract.EndContractBlock();
Win32Native.Color c = (Win32Native.Color) color;
// Make these background colors instead of foreground
if (isBackground)
c = (Win32Native.Color) ((int)c << 4);
return c;
}
[System.Security.SecurityCritical] // auto-generated
private static ConsoleColor ColorAttributeToConsoleColor(Win32Native.Color c)
{
// Turn background colors into foreground colors.
if ((c & Win32Native.Color.BackgroundMask) != 0)
c = (Win32Native.Color) (((int)c) >> 4);
return (ConsoleColor) c;
}
public static ConsoleColor BackgroundColor {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
bool succeeded;
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(false, out succeeded);
// For code that may be used from Windows app w/ no console
if (!succeeded)
return ConsoleColor.Black;
Win32Native.Color c = (Win32Native.Color) csbi.wAttributes & Win32Native.Color.BackgroundMask;
return ColorAttributeToConsoleColor(c);
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
Win32Native.Color c = ConsoleColorToColorAttribute(value, true);
bool succeeded;
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(false, out succeeded);
// For code that may be used from Windows app w/ no console
if (!succeeded)
return;
Contract.Assert(_haveReadDefaultColors, "Setting the foreground color before we've read the default foreground color!");
short attrs = csbi.wAttributes;
attrs &= ~((short)Win32Native.Color.BackgroundMask);
// C#'s bitwise-or sign-extends to 32 bits.
attrs = (short) (((uint) (ushort) attrs) | ((uint) (ushort) c));
// Ignore errors here - there are some scenarios for running code that wants
// to print in colors to the console in a Windows application.
Win32Native.SetConsoleTextAttribute(ConsoleOutputHandle, attrs);
}
} // public static ConsoleColor BackgroundColor
public static ConsoleColor ForegroundColor {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
bool succeeded;
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(false, out succeeded);
// For code that may be used from Windows app w/ no console
if (!succeeded)
return ConsoleColor.Gray;
Win32Native.Color c = (Win32Native.Color) csbi.wAttributes & Win32Native.Color.ForegroundMask;
return ColorAttributeToConsoleColor(c);
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
Win32Native.Color c = ConsoleColorToColorAttribute(value, false);
bool succeeded;
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(false, out succeeded);
// For code that may be used from Windows app w/ no console
if (!succeeded)
return;
Contract.Assert(_haveReadDefaultColors, "Setting the foreground color before we've read the default foreground color!");
short attrs = csbi.wAttributes;
attrs &= ~((short)Win32Native.Color.ForegroundMask);
// C#'s bitwise-or sign-extends to 32 bits.
attrs = (short) (((uint) (ushort) attrs) | ((uint) (ushort) c));
// Ignore errors here - there are some scenarios for running code that wants
// to print in colors to the console in a Windows application.
Win32Native.SetConsoleTextAttribute(ConsoleOutputHandle, attrs);
}
} // public static ConsoleColor ForegroundColor
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static void ResetColor()
{
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
bool succeeded;
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo(false, out succeeded);
// For code that may be used from Windows app w/ no console
if (!succeeded)
return;
Contract.Assert(_haveReadDefaultColors, "Setting the foreground color before we've read the default foreground color!");
short defaultAttrs = (short) (ushort) _defaultColors;
// Ignore errors here - there are some scenarios for running code that wants
// to print in colors to the console in a Windows application.
Win32Native.SetConsoleTextAttribute(ConsoleOutputHandle, defaultAttrs);
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static void MoveBufferArea(int sourceLeft, int sourceTop,
int sourceWidth, int sourceHeight, int targetLeft, int targetTop)
{
MoveBufferArea(sourceLeft, sourceTop, sourceWidth, sourceHeight, targetLeft, targetTop, ' ', ConsoleColor.Black, BackgroundColor);
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public unsafe static void MoveBufferArea(int sourceLeft, int sourceTop,
int sourceWidth, int sourceHeight, int targetLeft, int targetTop,
char sourceChar, ConsoleColor sourceForeColor,
ConsoleColor sourceBackColor)
{
if (sourceForeColor < ConsoleColor.Black || sourceForeColor > ConsoleColor.White)
throw new ArgumentException(Environment.GetResourceString("Arg_InvalidConsoleColor"), "sourceForeColor");
if (sourceBackColor < ConsoleColor.Black || sourceBackColor > ConsoleColor.White)
throw new ArgumentException(Environment.GetResourceString("Arg_InvalidConsoleColor"), "sourceBackColor");
Contract.EndContractBlock();
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
Win32Native.COORD bufferSize = csbi.dwSize;
if (sourceLeft < 0 || sourceLeft > bufferSize.X)
throw new ArgumentOutOfRangeException("sourceLeft", sourceLeft, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries"));
if (sourceTop < 0 || sourceTop > bufferSize.Y)
throw new ArgumentOutOfRangeException("sourceTop", sourceTop, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries"));
if (sourceWidth < 0 || sourceWidth > bufferSize.X - sourceLeft)
throw new ArgumentOutOfRangeException("sourceWidth", sourceWidth, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries"));
if (sourceHeight < 0 || sourceTop > bufferSize.Y - sourceHeight)
throw new ArgumentOutOfRangeException("sourceHeight", sourceHeight, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries"));
// Note: if the target range is partially in and partially out
// of the buffer, then we let the OS clip it for us.
if (targetLeft < 0 || targetLeft > bufferSize.X)
throw new ArgumentOutOfRangeException("targetLeft", targetLeft, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries"));
if (targetTop < 0 || targetTop > bufferSize.Y)
throw new ArgumentOutOfRangeException("targetTop", targetTop, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries"));
// If we're not doing any work, bail out now (Windows will return
// an error otherwise)
if (sourceWidth == 0 || sourceHeight == 0)
return;
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
// Read data from the original location, blank it out, then write
// it to the new location. This will handle overlapping source and
// destination regions correctly.
// See the "Reading and Writing Blocks of Characters and Attributes"
// sample for help
// Read the old data
Win32Native.CHAR_INFO[] data = new Win32Native.CHAR_INFO[sourceWidth * sourceHeight];
bufferSize.X = (short) sourceWidth;
bufferSize.Y = (short) sourceHeight;
Win32Native.COORD bufferCoord = new Win32Native.COORD();
Win32Native.SMALL_RECT readRegion = new Win32Native.SMALL_RECT();
readRegion.Left = (short) sourceLeft;
readRegion.Right = (short) (sourceLeft + sourceWidth - 1);
readRegion.Top = (short) sourceTop;
readRegion.Bottom = (short) (sourceTop + sourceHeight - 1);
bool r;
fixed(Win32Native.CHAR_INFO* pCharInfo = data)
r = Win32Native.ReadConsoleOutput(ConsoleOutputHandle, pCharInfo, bufferSize, bufferCoord, ref readRegion);
if (!r)
__Error.WinIOError();
// Overwrite old section
// I don't have a good function to blank out a rectangle.
Win32Native.COORD writeCoord = new Win32Native.COORD();
writeCoord.X = (short) sourceLeft;
Win32Native.Color c = ConsoleColorToColorAttribute(sourceBackColor, true);
c |= ConsoleColorToColorAttribute(sourceForeColor, false);
short attr = (short) c;
int numWritten;
for(int i = sourceTop; i<sourceTop + sourceHeight; i++) {
writeCoord.Y = (short) i;
r = Win32Native.FillConsoleOutputCharacter(ConsoleOutputHandle, sourceChar, sourceWidth, writeCoord, out numWritten);
Contract.Assert(numWritten == sourceWidth, "FillConsoleOutputCharacter wrote the wrong number of chars!");
if (!r)
__Error.WinIOError();
r = Win32Native.FillConsoleOutputAttribute(ConsoleOutputHandle, attr, sourceWidth, writeCoord, out numWritten);
if (!r)
__Error.WinIOError();
}
// Write text to new location
Win32Native.SMALL_RECT writeRegion = new Win32Native.SMALL_RECT();
writeRegion.Left = (short) targetLeft;
writeRegion.Right = (short) (targetLeft + sourceWidth);
writeRegion.Top = (short) targetTop;
writeRegion.Bottom = (short) (targetTop + sourceHeight);
fixed(Win32Native.CHAR_INFO* pCharInfo = data)
r = Win32Native.WriteConsoleOutput(ConsoleOutputHandle, pCharInfo, bufferSize, bufferCoord, ref writeRegion);
} // MoveBufferArea
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
private static Win32Native.CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo()
{
bool junk;
return GetBufferInfo(true, out junk);
}
// For apps that don't have a console (like Windows apps), they might
// run other code that includes color console output. Allow a mechanism
// where that code won't throw an exception for simple errors.
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
private static Win32Native.CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo(bool throwOnNoConsole, out bool succeeded)
{
succeeded = false;
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi;
bool success;
IntPtr hConsole = ConsoleOutputHandle;
if (hConsole == Win32Native.INVALID_HANDLE_VALUE) {
if (!throwOnNoConsole)
return new Win32Native.CONSOLE_SCREEN_BUFFER_INFO();
else
throw new IOException(Environment.GetResourceString("IO.IO_NoConsole"));
}
// Note that if stdout is redirected to a file, the console handle
// may be a file. If this fails, try stderr and stdin.
success = Win32Native.GetConsoleScreenBufferInfo(hConsole, out csbi);
if (!success) {
success = Win32Native.GetConsoleScreenBufferInfo(Win32Native.GetStdHandle(Win32Native.STD_ERROR_HANDLE), out csbi);
if (!success)
success = Win32Native.GetConsoleScreenBufferInfo(Win32Native.GetStdHandle(Win32Native.STD_INPUT_HANDLE), out csbi);
if (!success) {
int errorCode = Marshal.GetLastWin32Error();
if (errorCode == Win32Native.ERROR_INVALID_HANDLE && !throwOnNoConsole)
return new Win32Native.CONSOLE_SCREEN_BUFFER_INFO();
__Error.WinIOError(errorCode, null);
}
}
if (!_haveReadDefaultColors) {
// Fetch the default foreground and background color for the
// ResetColor method.
Contract.Assert((int)Win32Native.Color.ColorMask == 0xff, "Make sure one byte is large enough to store a Console color value!");
_defaultColors = (byte) (csbi.wAttributes & (short) Win32Native.Color.ColorMask);
_haveReadDefaultColors = true;
}
succeeded = true;
return csbi;
}
public static int BufferHeight {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
get {
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
return csbi.dwSize.Y;
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
SetBufferSize(BufferWidth, value);
}
}
public static int BufferWidth {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
get {
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
return csbi.dwSize.X;
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
SetBufferSize(value, BufferHeight);
}
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static void SetBufferSize(int width, int height)
{
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
// Ensure the new size is not smaller than the console window
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
Win32Native.SMALL_RECT srWindow = csbi.srWindow;
if (width < srWindow.Right + 1 || width >= Int16.MaxValue)
throw new ArgumentOutOfRangeException("width", width, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferLessThanWindowSize"));
if (height < srWindow.Bottom + 1 || height >= Int16.MaxValue)
throw new ArgumentOutOfRangeException("height", height, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferLessThanWindowSize"));
Win32Native.COORD size = new Win32Native.COORD();
size.X = (short) width;
size.Y = (short) height;
bool r = Win32Native.SetConsoleScreenBufferSize(ConsoleOutputHandle, size);
if (!r)
__Error.WinIOError();
}
public static int WindowHeight {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
return csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
SetWindowSize(WindowWidth, value);
}
}
public static int WindowWidth {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
return csbi.srWindow.Right - csbi.srWindow.Left + 1;
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
SetWindowSize(value, WindowHeight);
}
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static unsafe void SetWindowSize(int width, int height)
{
if (width <= 0)
throw new ArgumentOutOfRangeException("width", width, Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
if (height <= 0)
throw new ArgumentOutOfRangeException("height", height, Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
Contract.EndContractBlock();
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
// Get the position of the current console window
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
bool r;
// If the buffer is smaller than this new window size, resize the
// buffer to be large enough. Include window position.
bool resizeBuffer = false;
Win32Native.COORD size = new Win32Native.COORD();
size.X = csbi.dwSize.X;
size.Y = csbi.dwSize.Y;
if (csbi.dwSize.X < csbi.srWindow.Left + width) {
if (csbi.srWindow.Left >= Int16.MaxValue - width)
throw new ArgumentOutOfRangeException("width", Environment.GetResourceString("ArgumentOutOfRange_ConsoleWindowBufferSize"));
size.X = (short) (csbi.srWindow.Left + width);
resizeBuffer = true;
}
if (csbi.dwSize.Y < csbi.srWindow.Top + height) {
if (csbi.srWindow.Top >= Int16.MaxValue - height)
throw new ArgumentOutOfRangeException("height", Environment.GetResourceString("ArgumentOutOfRange_ConsoleWindowBufferSize"));
size.Y = (short) (csbi.srWindow.Top + height);
resizeBuffer = true;
}
if (resizeBuffer) {
r = Win32Native.SetConsoleScreenBufferSize(ConsoleOutputHandle, size);
if (!r)
__Error.WinIOError();
}
Win32Native.SMALL_RECT srWindow = csbi.srWindow;
// Preserve the position, but change the size.
srWindow.Bottom = (short) (srWindow.Top + height - 1);
srWindow.Right = (short) (srWindow.Left + width - 1);
r = Win32Native.SetConsoleWindowInfo(ConsoleOutputHandle, true, &srWindow);
if (!r) {
int errorCode = Marshal.GetLastWin32Error();
// If we resized the buffer, un-resize it.
if (resizeBuffer) {
Win32Native.SetConsoleScreenBufferSize(ConsoleOutputHandle, csbi.dwSize);
}
// Try to give a better error message here
Win32Native.COORD bounds = Win32Native.GetLargestConsoleWindowSize(ConsoleOutputHandle);
if (width > bounds.X)
throw new ArgumentOutOfRangeException("width", width, Environment.GetResourceString("ArgumentOutOfRange_ConsoleWindowSize_Size", bounds.X));
if (height > bounds.Y)
throw new ArgumentOutOfRangeException("height", height, Environment.GetResourceString("ArgumentOutOfRange_ConsoleWindowSize_Size", bounds.Y));
__Error.WinIOError(errorCode, String.Empty);
}
} // public static unsafe void SetWindowSize(int width, int height)
public static int LargestWindowWidth {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
// Note this varies based on current screen resolution and
// current console font. Do not cache this value.
Win32Native.COORD bounds = Win32Native.GetLargestConsoleWindowSize(ConsoleOutputHandle);
return bounds.X;
}
}
public static int LargestWindowHeight {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
// Note this varies based on current screen resolution and
// current console font. Do not cache this value.
Win32Native.COORD bounds = Win32Native.GetLargestConsoleWindowSize(ConsoleOutputHandle);
return bounds.Y;
}
}
public static int WindowLeft {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
return csbi.srWindow.Left;
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
SetWindowPosition(value, WindowTop);
}
}
public static int WindowTop {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
return csbi.srWindow.Top;
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
SetWindowPosition(WindowLeft, value);
}
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static unsafe void SetWindowPosition(int left, int top)
{
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
// Get the size of the current console window
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
Win32Native.SMALL_RECT srWindow = csbi.srWindow;
// Check for arithmetic underflows & overflows.
int newRight = left + srWindow.Right - srWindow.Left + 1;
if (left < 0 || newRight > csbi.dwSize.X || newRight < 0)
throw new ArgumentOutOfRangeException("left", left, Environment.GetResourceString("ArgumentOutOfRange_ConsoleWindowPos"));
int newBottom = top + srWindow.Bottom - srWindow.Top + 1;
if (top < 0 || newBottom > csbi.dwSize.Y || newBottom < 0)
throw new ArgumentOutOfRangeException("top", top, Environment.GetResourceString("ArgumentOutOfRange_ConsoleWindowPos"));
// Preserve the size, but move the position.
srWindow.Bottom -= (short) (srWindow.Top - top);
srWindow.Right -= (short) (srWindow.Left - left);
srWindow.Left = (short) left;
srWindow.Top = (short) top;
bool r = Win32Native.SetConsoleWindowInfo(ConsoleOutputHandle, true, &srWindow);
if (!r)
__Error.WinIOError();
}
public static int CursorLeft {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
return csbi.dwCursorPosition.X;
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
SetCursorPosition(value, CursorTop);
}
}
public static int CursorTop {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
return csbi.dwCursorPosition.Y;
}
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
SetCursorPosition(CursorLeft, value);
}
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static void SetCursorPosition(int left, int top)
{
// Note on argument checking - the upper bounds are NOT correct
// here! But it looks slightly expensive to compute them. Let
// Windows calculate them, then we'll give a nice error message.
if (left < 0 || left >= Int16.MaxValue)
throw new ArgumentOutOfRangeException("left", left, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries"));
if (top < 0 || top >= Int16.MaxValue)
throw new ArgumentOutOfRangeException("top", top, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries"));
Contract.EndContractBlock();
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
IntPtr hConsole = ConsoleOutputHandle;
Win32Native.COORD coords = new Win32Native.COORD();
coords.X = (short) left;
coords.Y = (short) top;
bool r = Win32Native.SetConsoleCursorPosition(hConsole, coords);
if (!r) {
// Give a nice error message for out of range sizes
int errorCode = Marshal.GetLastWin32Error();
Win32Native.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
if (left < 0 || left >= csbi.dwSize.X)
throw new ArgumentOutOfRangeException("left", left, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries"));
if (top < 0 || top >= csbi.dwSize.Y)
throw new ArgumentOutOfRangeException("top", top, Environment.GetResourceString("ArgumentOutOfRange_ConsoleBufferBoundaries"));
__Error.WinIOError(errorCode, String.Empty);
}
}
public static int CursorSize {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
Win32Native.CONSOLE_CURSOR_INFO cci;
IntPtr hConsole = ConsoleOutputHandle;
bool r = Win32Native.GetConsoleCursorInfo(hConsole, out cci);
if (!r)
__Error.WinIOError();
return cci.dwSize;
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
// Value should be a percentage from [1, 100].
if (value < 1 || value > 100)
throw new ArgumentOutOfRangeException("value", value, Environment.GetResourceString("ArgumentOutOfRange_CursorSize"));
Contract.EndContractBlock();
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
Win32Native.CONSOLE_CURSOR_INFO cci;
IntPtr hConsole = ConsoleOutputHandle;
bool r = Win32Native.GetConsoleCursorInfo(hConsole, out cci);
if (!r)
__Error.WinIOError();
cci.dwSize = value;
r = Win32Native.SetConsoleCursorInfo(hConsole, ref cci);
if (!r)
__Error.WinIOError();
}
}
public static bool CursorVisible {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
Win32Native.CONSOLE_CURSOR_INFO cci;
IntPtr hConsole = ConsoleOutputHandle;
bool r = Win32Native.GetConsoleCursorInfo(hConsole, out cci);
if (!r)
__Error.WinIOError();
return cci.bVisible;
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
Win32Native.CONSOLE_CURSOR_INFO cci;
IntPtr hConsole = ConsoleOutputHandle;
bool r = Win32Native.GetConsoleCursorInfo(hConsole, out cci);
if (!r)
__Error.WinIOError();
cci.bVisible = value;
r = Win32Native.SetConsoleCursorInfo(hConsole, ref cci);
if (!r)
__Error.WinIOError();
}
}
#if !FEATURE_CORECLR
[System.Security.SecurityCritical]
[DllImport(JitHelpers.QCall, CharSet = CharSet.Ansi)]
[ResourceExposure(ResourceScope.None)]
[SuppressUnmanagedCodeSecurity]
private static extern Int32 GetTitleNative(StringHandleOnStack outTitle, out Int32 outTitleLength);
public static String Title {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
string title = null;
int titleLength = -1;
Int32 r = GetTitleNative(JitHelpers.GetStringHandleOnStack(ref title), out titleLength);
if (0 != r) {
__Error.WinIOError(r, String.Empty);
}
if (titleLength > MaxConsoleTitleLength)
throw new InvalidOperationException(Environment.GetResourceString("ArgumentOutOfRange_ConsoleTitleTooLong"));
Contract.Assert(title.Length == titleLength);
return title;
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
set {
if (value == null)
throw new ArgumentNullException("value");
if (value.Length > MaxConsoleTitleLength)
throw new ArgumentOutOfRangeException("value", Environment.GetResourceString("ArgumentOutOfRange_ConsoleTitleTooLong"));
Contract.EndContractBlock();
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
if (!Win32Native.SetConsoleTitle(value))
__Error.WinIOError();
}
}
#endif // !FEATURE_CORECLR
[Flags]
internal enum ControlKeyState
{
RightAltPressed = 0x0001,
LeftAltPressed = 0x0002,
RightCtrlPressed = 0x0004,
LeftCtrlPressed = 0x0008,
ShiftPressed = 0x0010,
NumLockOn = 0x0020,
ScrollLockOn = 0x0040,
CapsLockOn = 0x0080,
EnhancedKey = 0x0100
}
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static ConsoleKeyInfo ReadKey()
{
return ReadKey(false);
}
// For tracking Alt+NumPad unicode key sequence. When you press Alt key down
// and press a numpad unicode decimal sequence and then release Alt key, the
// desired effect is to translate the sequence into one Unicode KeyPress.
// We need to keep track of the Alt+NumPad sequence and surface the final
// unicode char alone when the Alt key is released.
[System.Security.SecurityCritical] // auto-generated
private static bool IsAltKeyDown(Win32Native.InputRecord ir) {
return (((ControlKeyState) ir.keyEvent.controlKeyState)
& (ControlKeyState.LeftAltPressed | ControlKeyState.RightAltPressed)) != 0;
}
// Skip non key events. Generally we want to surface only KeyDown event
// and suppress KeyUp event from the same Key press but there are cases
// where the assumption of KeyDown-KeyUp pairing for a given key press
// is invalid. For example in IME Unicode keyboard input, we often see
// only KeyUp until the key is released.
[System.Security.SecurityCritical] // auto-generated
private static bool IsKeyDownEvent(Win32Native.InputRecord ir) {
return (ir.eventType == Win32Native.KEY_EVENT && ir.keyEvent.keyDown);
}
[System.Security.SecurityCritical] // auto-generated
private static bool IsModKey(Win32Native.InputRecord ir) {
// We should also skip over Shift, Control, and Alt, as well as caps lock.
// Apparently we don't need to check for 0xA0 through 0xA5, which are keys like
// Left Control & Right Control. See the ConsoleKey enum for these values.
short keyCode = ir.keyEvent.virtualKeyCode;
return ((keyCode >= 0x10 && keyCode <= 0x12)
|| keyCode == 0x14 || keyCode == 0x90 || keyCode == 0x91);
}
[System.Security.SecuritySafeCritical] // auto-generated
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static ConsoleKeyInfo ReadKey(bool intercept)
{
Win32Native.InputRecord ir;
int numEventsRead = -1;
bool r;
lock (ReadKeySyncObject) {
if (_cachedInputRecord.eventType == Win32Native.KEY_EVENT) {
// We had a previous keystroke with repeated characters.
ir = _cachedInputRecord;
if (_cachedInputRecord.keyEvent.repeatCount == 0)
_cachedInputRecord.eventType = -1;
else {
_cachedInputRecord.keyEvent.repeatCount--;
}
// We will return one key from this method, so we decrement the
// repeatCount here, leaving the cachedInputRecord in the "queue".
} else { // We did NOT have a previous keystroke with repeated characters:
while (true) {
r = Win32Native.ReadConsoleInput(ConsoleInputHandle, out ir, 1, out numEventsRead);
if (!r || numEventsRead == 0) {
// This will fail when stdin is redirected from a file or pipe.
// We could theoretically call Console.Read here, but I
// think we might do some things incorrectly then.
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ConsoleReadKeyOnFile"));
}
short keyCode = ir.keyEvent.virtualKeyCode;
// First check for non-keyboard events & discard them. Generally we tap into only KeyDown events and ignore the KeyUp events
// but it is possible that we are dealing with a Alt+NumPad unicode key sequence, the final unicode char is revealed only when
// the Alt key is released (i.e when the sequence is complete). To avoid noise, when the Alt key is down, we should eat up
// any intermediate key strokes (from NumPad) that collectively forms the Unicode character.
if (!IsKeyDownEvent(ir)) {
//
if (keyCode != AltVKCode)
continue;
}
char ch = (char) ir.keyEvent.uChar;
// In a Alt+NumPad unicode sequence, when the alt key is released uChar will represent the final unicode character, we need to
// surface this. VirtualKeyCode for this event will be Alt from the Alt-Up key event. This is probably not the right code,
// especially when we don't expose ConsoleKey.Alt, so this will end up being the hex value (0x12). VK_PACKET comes very
// close to being useful and something that we could look into using for this purpose...
if (ch == 0) {
// Skip mod keys.
if (IsModKey(ir))
continue;
}
// When Alt is down, it is possible that we are in the middle of a Alt+NumPad unicode sequence.
// Escape any intermediate NumPad keys whether NumLock is on or not (notepad behavior)
ConsoleKey key = (ConsoleKey) keyCode;
if (IsAltKeyDown(ir) && ((key >= ConsoleKey.NumPad0 && key <= ConsoleKey.NumPad9)
|| (key == ConsoleKey.Clear) || (key == ConsoleKey.Insert)
|| (key >= ConsoleKey.PageUp && key <= ConsoleKey.DownArrow))) {
continue;
}
if (ir.keyEvent.repeatCount > 1) {
ir.keyEvent.repeatCount--;
_cachedInputRecord = ir;
}
break;
}
} // we did NOT have a previous keystroke with repeated characters.
} // lock(ReadKeySyncObject)
ControlKeyState state = (ControlKeyState) ir.keyEvent.controlKeyState;
bool shift = (state & ControlKeyState.ShiftPressed) != 0;
bool alt = (state & (ControlKeyState.LeftAltPressed | ControlKeyState.RightAltPressed)) != 0;
bool control = (state & (ControlKeyState.LeftCtrlPressed | ControlKeyState.RightCtrlPressed)) != 0;
ConsoleKeyInfo info = new ConsoleKeyInfo((char)ir.keyEvent.uChar, (ConsoleKey) ir.keyEvent.virtualKeyCode, shift, alt, control);
if (!intercept)
Console.Write(ir.keyEvent.uChar);
return info;
} // public static ConsoleKeyInfo ReadKey(bool intercept)
public static bool KeyAvailable {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
[HostProtection(UI=true)]
get {
if (_cachedInputRecord.eventType == Win32Native.KEY_EVENT)
return true;
Win32Native.InputRecord ir = new Win32Native.InputRecord();
int numEventsRead = 0;
while (true) {
bool r = Win32Native.PeekConsoleInput(ConsoleInputHandle, out ir, 1, out numEventsRead);
if (!r) {
int errorCode = Marshal.GetLastWin32Error();
if (errorCode == Win32Native.ERROR_INVALID_HANDLE)
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ConsoleKeyAvailableOnFile"));
__Error.WinIOError(errorCode, "stdin");
}
if (numEventsRead == 0)
return false;
// Skip non key-down && mod key events.
if (!IsKeyDownEvent(ir) || IsModKey(ir)) {
//
// Exempt Alt keyUp for possible Alt+NumPad unicode sequence.
//short keyCode = ir.keyEvent.virtualKeyCode;
//if (!IsKeyDownEvent(ir) && (keyCode == AltVKCode))
// return true;
r = Win32Native.ReadConsoleInput(ConsoleInputHandle, out ir, 1, out numEventsRead);
if (!r)
__Error.WinIOError();
}
else {
return true;
}
}
} // get
} // public static bool KeyAvailable
public static bool NumberLock {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
get {
short s = Win32Native.GetKeyState(NumberLockVKCode);
return (s & 1) == 1;
}
}
public static bool CapsLock {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
get {
short s = Win32Native.GetKeyState(CapsLockVKCode);
return (s & 1) == 1;
}
}
public static bool TreatControlCAsInput {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Process, ResourceScope.Process)]
get {
IntPtr handle = ConsoleInputHandle;
if (handle == Win32Native.INVALID_HANDLE_VALUE)
throw new IOException(Environment.GetResourceString("IO.IO_NoConsole"));
int mode = 0;
bool r = Win32Native.GetConsoleMode(handle, out mode);
if (!r)
__Error.WinIOError();
return (mode & Win32Native.ENABLE_PROCESSED_INPUT) == 0;
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
set {
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
IntPtr handle = ConsoleInputHandle;
if (handle == Win32Native.INVALID_HANDLE_VALUE)
throw new IOException(Environment.GetResourceString("IO.IO_NoConsole"));
int mode = 0;
bool r = Win32Native.GetConsoleMode(handle, out mode);
if (value)
mode &= ~Win32Native.ENABLE_PROCESSED_INPUT;
else
mode |= Win32Native.ENABLE_PROCESSED_INPUT;
r = Win32Native.SetConsoleMode(handle, mode);
if (!r)
__Error.WinIOError();
}
}
#endif // !FEATURE_PAL
// During an appdomain unload, we must call into the OS and remove
// our delegate from the OS's list of console control handlers. If
// we don't do this, the OS will call back on a delegate that no
// longer exists. So, subclass CriticalFinalizableObject.
// This problem would theoretically exist during process exit for a
// single appdomain too, so using a critical finalizer is probably
// better than the appdomain unload event (I'm not sure we call that
// in the default appdomain during process exit).
internal sealed class ControlCHooker : CriticalFinalizerObject
{
private bool _hooked;
[System.Security.SecurityCritical] // auto-generated
private Win32Native.ConsoleCtrlHandlerRoutine _handler;
[System.Security.SecurityCritical] // auto-generated
internal ControlCHooker()
{
_handler = new Win32Native.ConsoleCtrlHandlerRoutine(BreakEvent);
}
[ResourceExposure(ResourceScope.None)]
[ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
~ControlCHooker()
{
Unhook();
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
internal void Hook()
{
if (!_hooked) {
bool r = Win32Native.SetConsoleCtrlHandler(_handler, true);
if (!r)
__Error.WinIOError();
_hooked = true;
}
}
[System.Security.SecuritySafeCritical] // auto-generated
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
internal void Unhook()
{
if (_hooked) {
bool r = Win32Native.SetConsoleCtrlHandler(_handler, false);
if (!r)
__Error.WinIOError();
_hooked = false;
}
}
} // internal sealed class ControlCHooker
// A class with data so ControlC handlers can be called on a Threadpool thread.
private sealed class ControlCDelegateData {
internal ConsoleSpecialKey ControlKey;
internal bool Cancel;
internal bool DelegateStarted;
internal ManualResetEvent CompletionEvent;
internal ConsoleCancelEventHandler CancelCallbacks;
internal ControlCDelegateData(ConsoleSpecialKey controlKey, ConsoleCancelEventHandler cancelCallbacks) {
this.ControlKey = controlKey;
this.CancelCallbacks = cancelCallbacks;
this.CompletionEvent = new ManualResetEvent(false);
// this.Cancel defaults to false
// this.DelegateStarted defaults to false
}
}
// Returns true if we've "handled" the break request, false if
// we want to terminate the process (or at least let the next
// control handler function have a chance).
private static bool BreakEvent(int controlType) {
// The thread that this gets called back on has a very small stack on 64 bit systems. There is
// not enough space to handle a managed exception being caught and thrown. So, queue up a work
// item on another thread for the actual event callback.
if (controlType == Win32Native.CTRL_C_EVENT ||
controlType == Win32Native.CTRL_BREAK_EVENT) {
// To avoid ---- between remove handler and raising the event
ConsoleCancelEventHandler cancelCallbacks = Console._cancelCallbacks;
if (cancelCallbacks == null) {
return false;
}
// Create the delegate
ConsoleSpecialKey controlKey = (controlType == 0) ? ConsoleSpecialKey.ControlC : ConsoleSpecialKey.ControlBreak;
ControlCDelegateData delegateData = new ControlCDelegateData(controlKey, cancelCallbacks);
WaitCallback controlCCallback = new WaitCallback(ControlCDelegate);
// Queue the delegate
if (!ThreadPool.QueueUserWorkItem(controlCCallback, delegateData)) {
Contract.Assert(false, "ThreadPool.QueueUserWorkItem returned false without throwing. Unable to execute ControlC handler");
return false;
}
// Block until the delegate is done. We need to be robust in the face of the work item not executing
// but we also want to get control back immediately after it is done and we don't want to give the
// handler a fixed time limit in case it needs to display UI. Wait on the event twice, once with a
// timout and a second time without if we are sure that the handler actually started.
TimeSpan controlCWaitTime = new TimeSpan(0, 0, 30); // 30 seconds
delegateData.CompletionEvent.WaitOne(controlCWaitTime, false);
if (!delegateData.DelegateStarted) {
Contract.Assert(false, "ThreadPool.QueueUserWorkItem did not execute the handler within 30 seconds.");
return false;
}
delegateData.CompletionEvent.WaitOne();
delegateData.CompletionEvent.Close();
return delegateData.Cancel;
}
return false;
}
// This is the worker delegate that is called on the Threadpool thread to fire the actual events. It must guarantee that it
// signals the caller on the ControlC thread so that it does not block indefinitely.
private static void ControlCDelegate(object data) {
ControlCDelegateData controlCData = (ControlCDelegateData)data;
try {
controlCData.DelegateStarted = true;
ConsoleCancelEventArgs args = new ConsoleCancelEventArgs(controlCData.ControlKey);
controlCData.CancelCallbacks(null, args);
controlCData.Cancel = args.Cancel;
}
finally {
controlCData.CompletionEvent.Set();
}
}
// Note: hooking this event allows you to prevent Control-C from
// killing a console app, which is somewhat surprising for users.
// Some permission seems appropriate. We chose UI permission for lack
// of a better one. However, we also applied host protection
// permission here as well, for self-affecting process management.
// This allows hosts to prevent people from adding a handler for
// this event.
public static event ConsoleCancelEventHandler CancelKeyPress {
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
add {
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
lock(InternalSyncObject) {
// Add this delegate to the pile.
_cancelCallbacks += value;
// If we haven't registered our control-C handler, do it.
if (_hooker == null) {
_hooker = new ControlCHooker();
_hooker.Hook();
}
}
}
[System.Security.SecuritySafeCritical] // auto-generated
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
remove {
new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
lock(InternalSyncObject) {
// If count was 0, call SetConsoleCtrlEvent to remove cb.
_cancelCallbacks -= value;
Contract.Assert(_cancelCallbacks == null || _cancelCallbacks.GetInvocationList().Length > 0, "Teach Console::CancelKeyPress to handle a non-null but empty list of callbacks");
if (_hooker != null && _cancelCallbacks == null)
_hooker.Unhook();
}
}
}
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static Stream OpenStandardError() {
return OpenStandardError(DefaultConsoleBufferSize);
}
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#endif
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static Stream OpenStandardError(int bufferSize) {
if (bufferSize < 0)
throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
return GetStandardFile(Win32Native.STD_ERROR_HANDLE,
FileAccess.Write, bufferSize);
}
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static Stream OpenStandardInput() {
return OpenStandardInput(DefaultConsoleBufferSize);
}
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#endif
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static Stream OpenStandardInput(int bufferSize) {
if (bufferSize < 0)
throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
return GetStandardFile(Win32Native.STD_INPUT_HANDLE,
FileAccess.Read, bufferSize);
}
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static Stream OpenStandardOutput() {
return OpenStandardOutput(DefaultConsoleBufferSize);
}
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#endif
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.Process)]
[ResourceConsumption(ResourceScope.Process)]
public static Stream OpenStandardOutput(int bufferSize) {
if (bufferSize < 0)
throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
Contract.EndContractBlock();
return GetStandardFile(Win32Native.STD_OUTPUT_HANDLE,
FileAccess.Write, bufferSize);
}
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#else
[System.Security.SecuritySafeCritical]
#endif
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.AppDomain)]
public static void SetIn(TextReader newIn) {
if (newIn == null)
throw new ArgumentNullException("newIn");
Contract.EndContractBlock();
#pragma warning disable 618
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
#pragma warning restore 618
newIn = TextReader.Synchronized(newIn);
lock(InternalSyncObject) {
_in = newIn;
}
}
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#else
[System.Security.SecuritySafeCritical]
#endif
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.AppDomain)]
public static void SetOut(TextWriter newOut) {
if (newOut == null)
throw new ArgumentNullException("newOut");
Contract.EndContractBlock();
#pragma warning disable 618
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
#pragma warning restore 618
#if FEATURE_CODEPAGES_FILE // if no codepages file then we are locked into default codepage and this field is not used
_isOutTextWriterRedirected = true;
#endif
newOut = TextWriter.Synchronized(newOut);
lock(InternalSyncObject) {
_out = newOut;
}
}
#if FEATURE_CORECLR
[System.Security.SecurityCritical] // auto-generated
#else
[System.Security.SecuritySafeCritical]
#endif
[HostProtection(UI=true)]
[ResourceExposure(ResourceScope.AppDomain)]
public static void SetError(TextWriter newError) {
if (newError == null)
throw new ArgumentNullException("newError");
Contract.EndContractBlock();
#pragma warning disable 618
new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
#pragma warning restore 618
#if FEATURE_CODEPAGES_FILE // if no codepages file then we are locked into default codepage and this field is not used
_isErrorTextWriterRedirected = true;
#endif
newError = TextWriter.Synchronized(newError);
lock(InternalSyncObject) {
_error = newError;
}
}
//
// Give a hint to the code generator to not inline the common console methods. The console methods are
// not performance critical. It is unnecessary code bloat to have them inlined.
//
// Moreover, simple repros for codegen bugs are often console-based. It is tedious to manually filter out
// the inlined console writelines from them.
//
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static int Read()
{
return In.Read();
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static String ReadLine()
{
return In.ReadLine();
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine()
{
Out.WriteLine();
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(bool value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(char value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(char[] buffer)
{
Out.WriteLine(buffer);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(char[] buffer, int index, int count)
{
Out.WriteLine(buffer, index, count);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(decimal value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(double value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(float value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(int value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(uint value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(long value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(ulong value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(Object value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(String value)
{
Out.WriteLine(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(String format, Object arg0)
{
Out.WriteLine(format, arg0);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(String format, Object arg0, Object arg1)
{
Out.WriteLine(format, arg0, arg1);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(String format, Object arg0, Object arg1, Object arg2)
{
Out.WriteLine(format, arg0, arg1, arg2);
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(String format, Object arg0, Object arg1, Object arg2,Object arg3, __arglist)
{
Object[] objArgs;
int argCount;
ArgIterator args = new ArgIterator(__arglist);
//+4 to account for the 4 hard-coded arguments at the beginning of the list.
argCount = args.GetRemainingCount() + 4;
objArgs = new Object[argCount];
//Handle the hard-coded arguments
objArgs[0] = arg0;
objArgs[1] = arg1;
objArgs[2] = arg2;
objArgs[3] = arg3;
//Walk all of the args in the variable part of the argument list.
for (int i=4; i<argCount; i++) {
objArgs[i] = TypedReference.ToObject(args.GetNextArg());
}
Out.WriteLine(format, objArgs);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void WriteLine(String format, params Object[] arg)
{
if (arg == null) // avoid ArgumentNullException from String.Format
Out.WriteLine(format, null, null); // faster than Out.WriteLine(format, (Object)arg);
else
Out.WriteLine(format, arg);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(String format, Object arg0)
{
Out.Write(format, arg0);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(String format, Object arg0, Object arg1)
{
Out.Write(format, arg0, arg1);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(String format, Object arg0, Object arg1, Object arg2)
{
Out.Write(format, arg0, arg1, arg2);
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(String format, Object arg0, Object arg1, Object arg2, Object arg3, __arglist)
{
Object[] objArgs;
int argCount;
ArgIterator args = new ArgIterator(__arglist);
//+4 to account for the 4 hard-coded arguments at the beginning of the list.
argCount = args.GetRemainingCount() + 4;
objArgs = new Object[argCount];
//Handle the hard-coded arguments
objArgs[0] = arg0;
objArgs[1] = arg1;
objArgs[2] = arg2;
objArgs[3] = arg3;
//Walk all of the args in the variable part of the argument list.
for (int i=4; i<argCount; i++) {
objArgs[i] = TypedReference.ToObject(args.GetNextArg());
}
Out.Write(format, objArgs);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(String format, params Object[] arg)
{
if (arg == null) // avoid ArgumentNullException from String.Format
Out.Write(format, null, null); // faster than Out.Write(format, (Object)arg);
else
Out.Write(format, arg);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(bool value)
{
Out.Write(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(char value)
{
Out.Write(value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(char[] buffer)
{
Out.Write(buffer);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(char[] buffer, int index, int count)
{
Out.Write(buffer, index, count);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(double value)
{
Out.Write (value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(decimal value)
{
Out.Write (value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(float value)
{
Out.Write (value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(int value)
{
Out.Write (value);
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(uint value)
{
Out.Write (value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(long value)
{
Out.Write (value);
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(ulong value)
{
Out.Write (value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(Object value)
{
Out.Write (value);
}
[HostProtection(UI=true)]
[MethodImplAttribute(MethodImplOptions.NoInlining)]
public static void Write(String value)
{
Out.Write (value);
}
} // public static class Console
} // namespace System
|