private static Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo(bool throwOnNoConsole, out bool succeeded)
{
succeeded = false;
IntPtr outputHandle = OutputHandle;
if (outputHandle == s_InvalidHandleValue)
{
if (throwOnNoConsole)
{
throw new IOException(SR.IO_NoConsole);
}
return new Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO();
}
// Note that if stdout is redirected to a file, the console handle may be a file.
// First try stdout; if this fails, try stderr and then stdin.
Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO csbi;
if (!Interop.Kernel32.GetConsoleScreenBufferInfo(outputHandle, out csbi) &&
!Interop.Kernel32.GetConsoleScreenBufferInfo(ErrorHandle, out csbi) &&
!Interop.Kernel32.GetConsoleScreenBufferInfo(InputHandle, out csbi))
{
int errorCode = Marshal.GetLastWin32Error();
if (errorCode == Interop.Errors.ERROR_INVALID_HANDLE && !throwOnNoConsole)
return new Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO();
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
}
if (!_haveReadDefaultColors)
{
// Fetch the default foreground and background color for the ResetColor method.
Debug.Assert((int)Interop.Kernel32.Color.ColorMask == 0xff, "Make sure one byte is large enough to store a Console color value!");
_defaultColors = (byte)(csbi.wAttributes & (short)Interop.Kernel32.Color.ColorMask);
_haveReadDefaultColors = true; // also used by ResetColor to know when GetBufferInfo has been called successfully
}
succeeded = true;
return csbi;
}