2015-04-07 09:35:12 +01:00
// ==++==
//
// 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 ;
}
}
2016-02-22 11:00:01 -05:00
//
// 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.
//
2015-04-07 09:35:12 +01:00
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static int Read ( )
{
return In . Read ( ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static String ReadLine ( )
{
return In . ReadLine ( ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( )
{
Out . WriteLine ( ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( bool value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( char value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( char [ ] buffer )
{
Out . WriteLine ( buffer ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( char [ ] buffer , int index , int count )
{
Out . WriteLine ( buffer , index , count ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( decimal value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( double value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( float value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( int value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( uint value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( long value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( ulong value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( Object value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( String value )
{
Out . WriteLine ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( String format , Object arg0 )
{
Out . WriteLine ( format , arg0 ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( String format , Object arg0 , Object arg1 )
{
Out . WriteLine ( format , arg0 , arg1 ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void WriteLine ( String format , Object arg0 , Object arg1 , Object arg2 )
{
Out . WriteLine ( format , arg0 , arg1 , arg2 ) ;
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
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)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
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)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( String format , Object arg0 )
{
Out . Write ( format , arg0 ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( String format , Object arg0 , Object arg1 )
{
Out . Write ( format , arg0 , arg1 ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( String format , Object arg0 , Object arg1 , Object arg2 )
{
Out . Write ( format , arg0 , arg1 , arg2 ) ;
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
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)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
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)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( bool value )
{
Out . Write ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( char value )
{
Out . Write ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( char [ ] buffer )
{
Out . Write ( buffer ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( char [ ] buffer , int index , int count )
{
Out . Write ( buffer , index , count ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( double value )
{
Out . Write ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( decimal value )
{
Out . Write ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( float value )
{
Out . Write ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( int value )
{
Out . Write ( value ) ;
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( uint value )
{
Out . Write ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( long value )
{
Out . Write ( value ) ;
}
[HostProtection(UI=true)]
[CLSCompliant(false)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( ulong value )
{
Out . Write ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( Object value )
{
Out . Write ( value ) ;
}
[HostProtection(UI=true)]
2016-02-22 11:00:01 -05:00
[MethodImplAttribute(MethodImplOptions.NoInlining)]
2015-04-07 09:35:12 +01:00
public static void Write ( String value )
{
Out . Write ( value ) ;
}
} // public static class Console
} // namespace System