public static unsafe void SetWindowSize(int width, int height)
{
if (width <= 0)
throw new ArgumentOutOfRangeException(nameof(width), width, SR.ArgumentOutOfRange_NeedPosNum);
if (height <= 0)
throw new ArgumentOutOfRangeException(nameof(height), height, SR.ArgumentOutOfRange_NeedPosNum);
// Get the position of the current console window
Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO csbi = GetBufferInfo();
// If the buffer is smaller than this new window size, resize the
// buffer to be large enough. Include window position.
bool resizeBuffer = false;
Interop.Kernel32.COORD size = new Interop.Kernel32.COORD();
size.X = csbi.dwSize.X;
size.Y = csbi.dwSize.Y;
if (csbi.dwSize.X < csbi.srWindow.Left + width)
{
if (csbi.srWindow.Left >= short.MaxValue - width)
throw new ArgumentOutOfRangeException(nameof(width), SR.ArgumentOutOfRange_ConsoleWindowBufferSize);
size.X = (short)(csbi.srWindow.Left + width);
resizeBuffer = true;
}
if (csbi.dwSize.Y < csbi.srWindow.Top + height)
{
if (csbi.srWindow.Top >= short.MaxValue - height)
throw new ArgumentOutOfRangeException(nameof(height), SR.ArgumentOutOfRange_ConsoleWindowBufferSize);
size.Y = (short)(csbi.srWindow.Top + height);
resizeBuffer = true;
}
if (resizeBuffer)
{
if (!Interop.Kernel32.SetConsoleScreenBufferSize(OutputHandle, size))
throw Win32Marshal.GetExceptionForWin32Error(Marshal.GetLastWin32Error());
}
Interop.Kernel32.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);
if (!Interop.Kernel32.SetConsoleWindowInfo(OutputHandle, true, &srWindow))
{
int errorCode = Marshal.GetLastWin32Error();
// If we resized the buffer, un-resize it.
if (resizeBuffer)
{
Interop.Kernel32.SetConsoleScreenBufferSize(OutputHandle, csbi.dwSize);
}
// Try to give a better error message here
Interop.Kernel32.COORD bounds = Interop.Kernel32.GetLargestConsoleWindowSize(OutputHandle);
if (width > bounds.X)
throw new ArgumentOutOfRangeException(nameof(width), width, SR.Format(SR.ArgumentOutOfRange_ConsoleWindowSize_Size, bounds.X));
if (height > bounds.Y)
throw new ArgumentOutOfRangeException(nameof(height), height, SR.Format(SR.ArgumentOutOfRange_ConsoleWindowSize_Size, bounds.Y));
throw Win32Marshal.GetExceptionForWin32Error(errorCode);
}
}