Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
ConsolePal.cs
Go to the documentation of this file.
1using System.IO;
3using System.Text;
4
5namespace System;
6
7internal static class ConsolePal
8{
9 [Flags]
10 internal enum ControlKeyState
11 {
16 ShiftPressed = 0x10,
17 NumLockOn = 0x20,
18 ScrollLockOn = 0x40,
19 CapsLockOn = 0x80,
20 EnhancedKey = 0x100
21 }
22
23 private sealed class WindowsConsoleStream : ConsoleStream
24 {
25 private readonly bool _isPipe;
26
27 private IntPtr _handle;
28
29 private readonly bool _useFileAPIs;
30
31 internal WindowsConsoleStream(IntPtr handle, FileAccess access, bool useFileAPIs)
32 : base(access)
33 {
35 _isPipe = global::Interop.Kernel32.GetFileType(handle) == 3;
36 _useFileAPIs = useFileAPIs;
37 }
38
39 protected override void Dispose(bool disposing)
40 {
42 base.Dispose(disposing);
43 }
44
45 public override int Read(Span<byte> buffer)
46 {
47 int bytesRead;
48 int num = ReadFileNative(_handle, buffer, _isPipe, out bytesRead, _useFileAPIs);
49 if (num != 0)
50 {
52 }
53 return bytesRead;
54 }
55
56 public override void Write(ReadOnlySpan<byte> buffer)
57 {
59 if (num != 0)
60 {
62 }
63 }
64
65 public override void Flush()
66 {
67 if (_handle == IntPtr.Zero)
68 {
69 throw Error.GetFileNotOpen();
70 }
71 base.Flush();
72 }
73
74 private unsafe static int ReadFileNative(IntPtr hFile, Span<byte> buffer, bool isPipe, out int bytesRead, bool useFileAPIs)
75 {
76 if (buffer.IsEmpty)
77 {
78 bytesRead = 0;
79 return 0;
80 }
81 bool flag;
82 fixed (byte* ptr = buffer)
83 {
84 if (useFileAPIs)
85 {
86 flag = global::Interop.Kernel32.ReadFile(hFile, ptr, buffer.Length, out bytesRead, IntPtr.Zero) != 0;
87 }
88 else
89 {
90 flag = global::Interop.Kernel32.ReadConsole(hFile, ptr, buffer.Length / 2, out var lpNumberOfCharsRead, IntPtr.Zero);
91 bytesRead = lpNumberOfCharsRead * 2;
92 }
93 }
94 if (flag)
95 {
96 return 0;
97 }
98 int lastPInvokeError = Marshal.GetLastPInvokeError();
99 if (lastPInvokeError == 232 || lastPInvokeError == 109)
100 {
101 return 0;
102 }
103 return lastPInvokeError;
104 }
105
106 private unsafe static int WriteFileNative(IntPtr hFile, ReadOnlySpan<byte> bytes, bool useFileAPIs)
107 {
108 if (bytes.IsEmpty)
109 {
110 return 0;
111 }
112 bool flag;
113 fixed (byte* ptr = bytes)
114 {
115 flag = ((!useFileAPIs) ? global::Interop.Kernel32.WriteConsole(hFile, ptr, bytes.Length / 2, out var _, IntPtr.Zero) : (global::Interop.Kernel32.WriteFile(hFile, ptr, bytes.Length, out var _, IntPtr.Zero) != 0));
116 }
117 if (flag)
118 {
119 return 0;
120 }
121 int lastPInvokeError = Marshal.GetLastPInvokeError();
122 if (lastPInvokeError == 232 || lastPInvokeError == 109)
123 {
124 return 0;
125 }
126 return lastPInvokeError;
127 }
128 }
129
130 private static readonly object s_readKeySyncObject = new object();
131
132 private static global::Interop.InputRecord _cachedInputRecord;
133
134 private static volatile bool _haveReadDefaultColors;
135
136 private static volatile byte _defaultColors;
137
138 private static IntPtr InvalidHandleValue => new IntPtr(-1);
139
140 private static IntPtr InputHandle => global::Interop.Kernel32.GetStdHandle(-10);
141
142 private static IntPtr OutputHandle => global::Interop.Kernel32.GetStdHandle(-11);
143
144 private static IntPtr ErrorHandle => global::Interop.Kernel32.GetStdHandle(-12);
145
146 public static Encoding InputEncoding => EncodingHelper.GetSupportedConsoleEncoding((int)global::Interop.Kernel32.GetConsoleCP());
147
148 public static Encoding OutputEncoding => EncodingHelper.GetSupportedConsoleEncoding((int)global::Interop.Kernel32.GetConsoleOutputCP());
149
150 public static bool NumberLock
151 {
152 get
153 {
154 try
155 {
156 short keyState = global::Interop.User32.GetKeyState(144);
157 return (keyState & 1) == 1;
158 }
159 catch (Exception)
160 {
162 }
163 }
164 }
165
166 public static bool CapsLock
167 {
168 get
169 {
170 try
171 {
172 short keyState = global::Interop.User32.GetKeyState(20);
173 return (keyState & 1) == 1;
174 }
175 catch (Exception)
176 {
178 }
179 }
180 }
181
182 public static bool KeyAvailable
183 {
184 get
185 {
186 if (_cachedInputRecord.eventType == 1)
187 {
188 return true;
189 }
190 global::Interop.InputRecord buffer = default(global::Interop.InputRecord);
191 int numEventsRead = 0;
192 while (true)
193 {
194 if (!global::Interop.Kernel32.PeekConsoleInput(InputHandle, out buffer, 1, out numEventsRead))
195 {
196 int lastPInvokeError = Marshal.GetLastPInvokeError();
197 if (lastPInvokeError == 6)
198 {
200 }
201 throw System.IO.Win32Marshal.GetExceptionForWin32Error(lastPInvokeError, "stdin");
202 }
203 if (numEventsRead == 0)
204 {
205 return false;
206 }
208 {
209 break;
210 }
211 if (!global::Interop.Kernel32.ReadConsoleInput(InputHandle, out buffer, 1, out numEventsRead))
212 {
214 }
215 }
216 return true;
217 }
218 }
219
220 public static bool TreatControlCAsInput
221 {
222 get
223 {
224 IntPtr inputHandle = InputHandle;
225 if (inputHandle == InvalidHandleValue)
226 {
228 }
229 int mode = 0;
230 if (!global::Interop.Kernel32.GetConsoleMode(inputHandle, out mode))
231 {
233 }
234 return (mode & 1) == 0;
235 }
236 set
237 {
238 IntPtr inputHandle = InputHandle;
239 if (inputHandle == InvalidHandleValue)
240 {
242 }
243 int mode = 0;
244 if (!global::Interop.Kernel32.GetConsoleMode(inputHandle, out mode))
245 {
247 }
248 mode = ((!value) ? (mode | 1) : (mode & -2));
249 if (!global::Interop.Kernel32.SetConsoleMode(inputHandle, mode))
250 {
252 }
253 }
254 }
255
257 {
258 get
259 {
260 bool succeeded;
261 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo(throwOnNoConsole: false, out succeeded);
262 if (!succeeded)
263 {
264 return ConsoleColor.Black;
265 }
266 return ColorAttributeToConsoleColor((global::Interop.Kernel32.Color)(bufferInfo.wAttributes & 0xF0));
267 }
268 set
269 {
270 global::Interop.Kernel32.Color color = ConsoleColorToColorAttribute(value, isBackground: true);
271 bool succeeded;
272 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo(throwOnNoConsole: false, out succeeded);
273 if (succeeded)
274 {
275 short wAttributes = bufferInfo.wAttributes;
276 wAttributes &= -241;
277 wAttributes = (short)((ushort)wAttributes | (ushort)color);
278 global::Interop.Kernel32.SetConsoleTextAttribute(OutputHandle, wAttributes);
279 }
280 }
281 }
282
284 {
285 get
286 {
287 bool succeeded;
288 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo(throwOnNoConsole: false, out succeeded);
289 if (!succeeded)
290 {
291 return ConsoleColor.Gray;
292 }
293 return ColorAttributeToConsoleColor((global::Interop.Kernel32.Color)(bufferInfo.wAttributes & 0xF));
294 }
295 set
296 {
297 global::Interop.Kernel32.Color color = ConsoleColorToColorAttribute(value, isBackground: false);
298 bool succeeded;
299 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo(throwOnNoConsole: false, out succeeded);
300 if (succeeded)
301 {
302 short wAttributes = bufferInfo.wAttributes;
303 wAttributes &= -16;
304 wAttributes = (short)((ushort)wAttributes | (ushort)color);
305 global::Interop.Kernel32.SetConsoleTextAttribute(OutputHandle, wAttributes);
306 }
307 }
308 }
309
310 public static int CursorSize
311 {
312 get
313 {
314 if (!global::Interop.Kernel32.GetConsoleCursorInfo(OutputHandle, out var cci))
315 {
317 }
318 return cci.dwSize;
319 }
320 set
321 {
322 if (value < 1 || value > 100)
323 {
325 }
326 if (!global::Interop.Kernel32.GetConsoleCursorInfo(OutputHandle, out var cci))
327 {
329 }
330 cci.dwSize = value;
331 if (!global::Interop.Kernel32.SetConsoleCursorInfo(OutputHandle, ref cci))
332 {
334 }
335 }
336 }
337
338 public static bool CursorVisible
339 {
340 get
341 {
342 if (!global::Interop.Kernel32.GetConsoleCursorInfo(OutputHandle, out var cci))
343 {
345 }
346 return cci.bVisible;
347 }
348 set
349 {
350 if (!global::Interop.Kernel32.GetConsoleCursorInfo(OutputHandle, out var cci))
351 {
353 }
354 cci.bVisible = value;
355 if (!global::Interop.Kernel32.SetConsoleCursorInfo(OutputHandle, ref cci))
356 {
358 }
359 }
360 }
361
362 public unsafe static string Title
363 {
364 get
365 {
366 Span<char> initialBuffer = stackalloc char[256];
367 System.Text.ValueStringBuilder valueStringBuilder = new System.Text.ValueStringBuilder(initialBuffer);
368 uint num;
369 while (true)
370 {
371 num = 0u;
372 fixed (char* title = valueStringBuilder)
373 {
374 num = global::Interop.Kernel32.GetConsoleTitleW(title, (uint)valueStringBuilder.Capacity);
375 }
376 if (num == 0)
377 {
378 int lastPInvokeError = Marshal.GetLastPInvokeError();
379 switch (lastPInvokeError)
380 {
381 case 122:
382 valueStringBuilder.EnsureCapacity(valueStringBuilder.Capacity * 2);
383 continue;
384 default:
385 throw System.IO.Win32Marshal.GetExceptionForWin32Error(lastPInvokeError, string.Empty);
386 case 0:
387 break;
388 }
389 break;
390 }
391 if (num < valueStringBuilder.Capacity - 1 && (!IsWindows7() || num < valueStringBuilder.Capacity / 2 - 1))
392 {
393 break;
394 }
395 valueStringBuilder.EnsureCapacity(valueStringBuilder.Capacity * 2);
396 }
397 valueStringBuilder.Length = (int)num;
398 return valueStringBuilder.ToString();
399 }
400 set
401 {
402 if (!global::Interop.Kernel32.SetConsoleTitle(value))
403 {
405 }
406 }
407 }
408
409 public static int BufferWidth
410 {
411 get
412 {
413 return GetBufferInfo().dwSize.X;
414 }
415 set
416 {
418 }
419 }
420
421 public static int BufferHeight
422 {
423 get
424 {
425 return GetBufferInfo().dwSize.Y;
426 }
427 set
428 {
430 }
431 }
432
433 public static int LargestWindowWidth => global::Interop.Kernel32.GetLargestConsoleWindowSize(OutputHandle).X;
434
435 public static int LargestWindowHeight => global::Interop.Kernel32.GetLargestConsoleWindowSize(OutputHandle).Y;
436
437 public static int WindowLeft
438 {
439 get
440 {
441 return GetBufferInfo().srWindow.Left;
442 }
443 set
444 {
446 }
447 }
448
449 public static int WindowTop
450 {
451 get
452 {
453 return GetBufferInfo().srWindow.Top;
454 }
455 set
456 {
458 }
459 }
460
461 public static int WindowWidth
462 {
463 get
464 {
465 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo();
466 return bufferInfo.srWindow.Right - bufferInfo.srWindow.Left + 1;
467 }
468 set
469 {
471 }
472 }
473
474 public static int WindowHeight
475 {
476 get
477 {
478 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo();
479 return bufferInfo.srWindow.Bottom - bufferInfo.srWindow.Top + 1;
480 }
481 set
482 {
484 }
485 }
486
487 internal static void EnsureConsoleInitialized()
488 {
489 }
490
491 private static bool IsWindows7()
492 {
493 Version version = Environment.OSVersion.Version;
494 if (version.Major == 6)
495 {
496 return version.Minor == 1;
497 }
498 return false;
499 }
500
501 public static Stream OpenStandardInput()
502 {
503 return GetStandardFile(-10, FileAccess.Read, Console.InputEncoding.CodePage != 1200 || Console.IsInputRedirected);
504 }
505
507 {
508 return GetStandardFile(-11, FileAccess.Write, Console.OutputEncoding.CodePage != 1200 || Console.IsOutputRedirected);
509 }
510
511 public static Stream OpenStandardError()
512 {
513 return GetStandardFile(-12, FileAccess.Write, Console.OutputEncoding.CodePage != 1200 || Console.IsErrorRedirected);
514 }
515
516 private static Stream GetStandardFile(int handleType, FileAccess access, bool useFileAPIs)
517 {
518 IntPtr stdHandle = global::Interop.Kernel32.GetStdHandle(handleType);
519 if (stdHandle == IntPtr.Zero || stdHandle == InvalidHandleValue || (access != FileAccess.Read && !ConsoleHandleIsWritable(stdHandle)))
520 {
521 return Stream.Null;
522 }
523 return new WindowsConsoleStream(stdHandle, access, useFileAPIs);
524 }
525
526 private unsafe static bool ConsoleHandleIsWritable(IntPtr outErrHandle)
527 {
528 byte b = 65;
529 int numBytesWritten;
530 int num = global::Interop.Kernel32.WriteFile(outErrHandle, &b, 0, out numBytesWritten, IntPtr.Zero);
531 return num != 0;
532 }
533
534 public static void SetConsoleInputEncoding(Encoding enc)
535 {
536 if (enc.CodePage != 1200 && !global::Interop.Kernel32.SetConsoleCP(enc.CodePage))
537 {
539 }
540 }
541
542 public static void SetConsoleOutputEncoding(Encoding enc)
543 {
544 if (enc.CodePage != 1200 && !global::Interop.Kernel32.SetConsoleOutputCP(enc.CodePage))
545 {
547 }
548 }
549
550 public static bool IsInputRedirectedCore()
551 {
553 }
554
555 public static bool IsOutputRedirectedCore()
556 {
558 }
559
560 public static bool IsErrorRedirectedCore()
561 {
563 }
564
565 private static bool IsHandleRedirected(IntPtr handle)
566 {
567 uint fileType = global::Interop.Kernel32.GetFileType(handle);
568 if ((fileType & 2) != 2)
569 {
570 return true;
571 }
572 return !global::Interop.Kernel32.IsGetConsoleModeCallSuccessful(handle);
573 }
574
576 {
578 return SyncTextReader.GetSynchronizedTextReader((stream == Stream.Null) ? StreamReader.Null : new StreamReader(stream, new ConsoleEncoding(Console.InputEncoding), detectEncodingFromByteOrderMarks: false, 4096, leaveOpen: true));
579 }
580
581 private static bool IsKeyDownEvent(global::Interop.InputRecord ir)
582 {
583 if (ir.eventType == 1)
584 {
585 return ir.keyEvent.keyDown != global::Interop.BOOL.FALSE;
586 }
587 return false;
588 }
589
590 private static bool IsModKey(global::Interop.InputRecord ir)
591 {
592 short virtualKeyCode = ir.keyEvent.virtualKeyCode;
593 if ((virtualKeyCode < 16 || virtualKeyCode > 18) && virtualKeyCode != 20 && virtualKeyCode != 144)
594 {
595 return virtualKeyCode == 145;
596 }
597 return true;
598 }
599
600 private static bool IsAltKeyDown(global::Interop.InputRecord ir)
601 {
602 return (ir.keyEvent.controlKeyState & 3) != 0;
603 }
604
605 public static ConsoleKeyInfo ReadKey(bool intercept)
606 {
607 int numEventsRead = -1;
608 global::Interop.InputRecord buffer;
610 {
611 if (_cachedInputRecord.eventType == 1)
612 {
614 if (_cachedInputRecord.keyEvent.repeatCount == 0)
615 {
616 _cachedInputRecord.eventType = -1;
617 }
618 else
619 {
620 _cachedInputRecord.keyEvent.repeatCount--;
621 }
622 }
623 else
624 {
625 while (true)
626 {
627 if (!global::Interop.Kernel32.ReadConsoleInput(InputHandle, out buffer, 1, out numEventsRead) || numEventsRead == 0)
628 {
630 }
631 short virtualKeyCode = buffer.keyEvent.virtualKeyCode;
632 if ((!IsKeyDownEvent(buffer) && virtualKeyCode != 18) || (buffer.keyEvent.uChar == '\0' && IsModKey(buffer)))
633 {
634 continue;
635 }
636 ConsoleKey consoleKey = (ConsoleKey)virtualKeyCode;
637 if (!IsAltKeyDown(buffer))
638 {
639 break;
640 }
641 if (consoleKey < ConsoleKey.NumPad0 || consoleKey > ConsoleKey.NumPad9)
642 {
643 switch (consoleKey)
644 {
645 case ConsoleKey.Clear:
646 case ConsoleKey.PageUp:
647 case ConsoleKey.PageDown:
648 case ConsoleKey.End:
649 case ConsoleKey.Home:
650 case ConsoleKey.LeftArrow:
651 case ConsoleKey.UpArrow:
652 case ConsoleKey.RightArrow:
653 case ConsoleKey.DownArrow:
654 case ConsoleKey.Insert:
655 continue;
656 }
657 break;
658 }
659 }
660 if (buffer.keyEvent.repeatCount > 1)
661 {
662 buffer.keyEvent.repeatCount--;
664 }
665 }
666 }
667 ControlKeyState controlKeyState = (ControlKeyState)buffer.keyEvent.controlKeyState;
668 bool shift = (controlKeyState & ControlKeyState.ShiftPressed) != 0;
669 bool alt = (controlKeyState & (ControlKeyState.RightAltPressed | ControlKeyState.LeftAltPressed)) != 0;
670 bool control = (controlKeyState & (ControlKeyState.RightCtrlPressed | ControlKeyState.LeftCtrlPressed)) != 0;
671 ConsoleKeyInfo result = new ConsoleKeyInfo(buffer.keyEvent.uChar, (ConsoleKey)buffer.keyEvent.virtualKeyCode, shift, alt, control);
672 if (!intercept)
673 {
674 Console.Write(buffer.keyEvent.uChar);
675 }
676 return result;
677 }
678
679 public static void ResetColor()
680 {
682 {
683 GetBufferInfo(throwOnNoConsole: false, out var succeeded);
684 if (!succeeded)
685 {
686 return;
687 }
688 }
689 global::Interop.Kernel32.SetConsoleTextAttribute(OutputHandle, _defaultColors);
690 }
691
692 public static (int Left, int Top) GetCursorPosition()
693 {
694 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo();
695 return (Left: bufferInfo.dwCursorPosition.X, Top: bufferInfo.dwCursorPosition.Y);
696 }
697
698 public static void Beep()
699 {
700 global::Interop.Kernel32.Beep(800, 200);
701 }
702
703 public static void Beep(int frequency, int duration)
704 {
705 if (frequency < 37 || frequency > 32767)
706 {
707 throw new ArgumentOutOfRangeException("frequency", frequency, System.SR.Format(System.SR.ArgumentOutOfRange_BeepFrequency, 37, 32767));
708 }
709 if (duration <= 0)
710 {
712 }
713 global::Interop.Kernel32.Beep(frequency, duration);
714 }
715
716 public unsafe static void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop, char sourceChar, ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
717 {
718 if (sourceForeColor < ConsoleColor.Black || sourceForeColor > ConsoleColor.White)
719 {
720 throw new ArgumentException(System.SR.Arg_InvalidConsoleColor, "sourceForeColor");
721 }
722 if (sourceBackColor < ConsoleColor.Black || sourceBackColor > ConsoleColor.White)
723 {
724 throw new ArgumentException(System.SR.Arg_InvalidConsoleColor, "sourceBackColor");
725 }
726 global::Interop.Kernel32.COORD dwSize = GetBufferInfo().dwSize;
727 if (sourceLeft < 0 || sourceLeft > dwSize.X)
728 {
730 }
731 if (sourceTop < 0 || sourceTop > dwSize.Y)
732 {
734 }
735 if (sourceWidth < 0 || sourceWidth > dwSize.X - sourceLeft)
736 {
738 }
739 if (sourceHeight < 0 || sourceTop > dwSize.Y - sourceHeight)
740 {
742 }
743 if (targetLeft < 0 || targetLeft > dwSize.X)
744 {
746 }
747 if (targetTop < 0 || targetTop > dwSize.Y)
748 {
750 }
751 if (sourceWidth == 0 || sourceHeight == 0)
752 {
753 return;
754 }
755 global::Interop.Kernel32.CHAR_INFO[] array = new global::Interop.Kernel32.CHAR_INFO[sourceWidth * sourceHeight];
756 dwSize.X = (short)sourceWidth;
757 dwSize.Y = (short)sourceHeight;
758 global::Interop.Kernel32.COORD bufferCoord = default(global::Interop.Kernel32.COORD);
759 global::Interop.Kernel32.SMALL_RECT readRegion = default(global::Interop.Kernel32.SMALL_RECT);
760 readRegion.Left = (short)sourceLeft;
761 readRegion.Right = (short)(sourceLeft + sourceWidth - 1);
762 readRegion.Top = (short)sourceTop;
763 readRegion.Bottom = (short)(sourceTop + sourceHeight - 1);
764 bool flag;
765 fixed (global::Interop.Kernel32.CHAR_INFO* pBuffer = array)
766 {
767 flag = global::Interop.Kernel32.ReadConsoleOutput(OutputHandle, pBuffer, dwSize, bufferCoord, ref readRegion);
768 }
769 if (!flag)
770 {
772 }
773 global::Interop.Kernel32.COORD cOORD = default(global::Interop.Kernel32.COORD);
774 cOORD.X = (short)sourceLeft;
775 global::Interop.Kernel32.Color color = ConsoleColorToColorAttribute(sourceBackColor, isBackground: true);
776 color |= ConsoleColorToColorAttribute(sourceForeColor, isBackground: false);
777 short wColorAttribute = (short)color;
778 for (int i = sourceTop; i < sourceTop + sourceHeight; i++)
779 {
780 cOORD.Y = (short)i;
781 if (!global::Interop.Kernel32.FillConsoleOutputCharacter(OutputHandle, sourceChar, sourceWidth, cOORD, out var pNumCharsWritten))
782 {
784 }
785 if (!global::Interop.Kernel32.FillConsoleOutputAttribute(OutputHandle, wColorAttribute, sourceWidth, cOORD, out pNumCharsWritten))
786 {
788 }
789 }
790 global::Interop.Kernel32.SMALL_RECT writeRegion = default(global::Interop.Kernel32.SMALL_RECT);
791 writeRegion.Left = (short)targetLeft;
792 writeRegion.Right = (short)(targetLeft + sourceWidth);
793 writeRegion.Top = (short)targetTop;
794 writeRegion.Bottom = (short)(targetTop + sourceHeight);
795 fixed (global::Interop.Kernel32.CHAR_INFO* buffer = array)
796 {
797 global::Interop.Kernel32.WriteConsoleOutput(OutputHandle, buffer, dwSize, bufferCoord, ref writeRegion);
798 }
799 }
800
801 public static void Clear()
802 {
803 global::Interop.Kernel32.COORD cOORD = default(global::Interop.Kernel32.COORD);
804 IntPtr outputHandle = OutputHandle;
805 if (outputHandle == InvalidHandleValue)
806 {
808 }
809 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo();
810 int num = bufferInfo.dwSize.X * bufferInfo.dwSize.Y;
811 int pNumCharsWritten = 0;
812 if (!global::Interop.Kernel32.FillConsoleOutputCharacter(outputHandle, ' ', num, cOORD, out pNumCharsWritten))
813 {
815 }
816 pNumCharsWritten = 0;
817 if (!global::Interop.Kernel32.FillConsoleOutputAttribute(outputHandle, bufferInfo.wAttributes, num, cOORD, out pNumCharsWritten))
818 {
820 }
821 if (!global::Interop.Kernel32.SetConsoleCursorPosition(outputHandle, cOORD))
822 {
824 }
825 }
826
827 public static void SetCursorPosition(int left, int top)
828 {
829 IntPtr outputHandle = OutputHandle;
830 global::Interop.Kernel32.COORD cursorPosition = default(global::Interop.Kernel32.COORD);
831 cursorPosition.X = (short)left;
832 cursorPosition.Y = (short)top;
833 if (!global::Interop.Kernel32.SetConsoleCursorPosition(outputHandle, cursorPosition))
834 {
835 int lastPInvokeError = Marshal.GetLastPInvokeError();
836 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo();
837 if (left >= bufferInfo.dwSize.X)
838 {
840 }
841 if (top >= bufferInfo.dwSize.Y)
842 {
844 }
845 throw System.IO.Win32Marshal.GetExceptionForWin32Error(lastPInvokeError);
846 }
847 }
848
849 public static void SetBufferSize(int width, int height)
850 {
851 global::Interop.Kernel32.SMALL_RECT srWindow = GetBufferInfo().srWindow;
852 if (width < srWindow.Right + 1 || width >= 32767)
853 {
855 }
856 if (height < srWindow.Bottom + 1 || height >= 32767)
857 {
859 }
860 global::Interop.Kernel32.COORD size = default(global::Interop.Kernel32.COORD);
861 size.X = (short)width;
862 size.Y = (short)height;
863 if (!global::Interop.Kernel32.SetConsoleScreenBufferSize(OutputHandle, size))
864 {
866 }
867 }
868
869 public unsafe static void SetWindowPosition(int left, int top)
870 {
871 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo();
872 global::Interop.Kernel32.SMALL_RECT srWindow = bufferInfo.srWindow;
873 int num = left + srWindow.Right - srWindow.Left;
874 if (left < 0 || num > bufferInfo.dwSize.X - 1 || num < left)
875 {
877 }
878 int num2 = top + srWindow.Bottom - srWindow.Top;
879 if (top < 0 || num2 > bufferInfo.dwSize.Y - 1 || num2 < top)
880 {
882 }
883 srWindow.Bottom = (short)num2;
884 srWindow.Right = (short)num;
885 srWindow.Left = (short)left;
886 srWindow.Top = (short)top;
887 if (!global::Interop.Kernel32.SetConsoleWindowInfo(OutputHandle, absolute: true, &srWindow))
888 {
890 }
891 }
892
893 public unsafe static void SetWindowSize(int width, int height)
894 {
895 if (width <= 0)
896 {
898 }
899 if (height <= 0)
900 {
902 }
903 global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO bufferInfo = GetBufferInfo();
904 bool flag = false;
905 global::Interop.Kernel32.COORD size = default(global::Interop.Kernel32.COORD);
906 size.X = bufferInfo.dwSize.X;
907 size.Y = bufferInfo.dwSize.Y;
908 if (bufferInfo.dwSize.X < bufferInfo.srWindow.Left + width)
909 {
910 if (bufferInfo.srWindow.Left >= 32767 - width)
911 {
913 }
914 size.X = (short)(bufferInfo.srWindow.Left + width);
915 flag = true;
916 }
917 if (bufferInfo.dwSize.Y < bufferInfo.srWindow.Top + height)
918 {
919 if (bufferInfo.srWindow.Top >= 32767 - height)
920 {
922 }
923 size.Y = (short)(bufferInfo.srWindow.Top + height);
924 flag = true;
925 }
926 if (flag && !global::Interop.Kernel32.SetConsoleScreenBufferSize(OutputHandle, size))
927 {
929 }
930 global::Interop.Kernel32.SMALL_RECT srWindow = bufferInfo.srWindow;
931 srWindow.Bottom = (short)(srWindow.Top + height - 1);
932 srWindow.Right = (short)(srWindow.Left + width - 1);
933 if (!global::Interop.Kernel32.SetConsoleWindowInfo(OutputHandle, absolute: true, &srWindow))
934 {
935 int lastPInvokeError = Marshal.GetLastPInvokeError();
936 if (flag)
937 {
938 global::Interop.Kernel32.SetConsoleScreenBufferSize(OutputHandle, bufferInfo.dwSize);
939 }
940 global::Interop.Kernel32.COORD largestConsoleWindowSize = global::Interop.Kernel32.GetLargestConsoleWindowSize(OutputHandle);
941 if (width > largestConsoleWindowSize.X)
942 {
943 throw new ArgumentOutOfRangeException("width", width, System.SR.Format(System.SR.ArgumentOutOfRange_ConsoleWindowSize_Size, largestConsoleWindowSize.X));
944 }
945 if (height > largestConsoleWindowSize.Y)
946 {
947 throw new ArgumentOutOfRangeException("height", height, System.SR.Format(System.SR.ArgumentOutOfRange_ConsoleWindowSize_Size, largestConsoleWindowSize.Y));
948 }
949 throw System.IO.Win32Marshal.GetExceptionForWin32Error(lastPInvokeError);
950 }
951 }
952
953 private static global::Interop.Kernel32.Color ConsoleColorToColorAttribute(ConsoleColor color, bool isBackground)
954 {
955 if (((uint)color & 0xFFFFFFF0u) != 0)
956 {
958 }
959 global::Interop.Kernel32.Color color2 = (global::Interop.Kernel32.Color)color;
960 if (isBackground)
961 {
962 color2 = (global::Interop.Kernel32.Color)((int)color2 << 4);
963 }
964 return color2;
965 }
966
967 private static ConsoleColor ColorAttributeToConsoleColor(global::Interop.Kernel32.Color c)
968 {
969 if ((c & global::Interop.Kernel32.Color.BackgroundMask) != 0)
970 {
971 c = (global::Interop.Kernel32.Color)((int)c >> 4);
972 }
973 return (ConsoleColor)c;
974 }
975
976 private static global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo()
977 {
978 bool succeeded;
979 return GetBufferInfo(throwOnNoConsole: true, out succeeded);
980 }
981
982 private static global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo(bool throwOnNoConsole, out bool succeeded)
983 {
984 succeeded = false;
985 IntPtr outputHandle = OutputHandle;
986 if (outputHandle == InvalidHandleValue)
987 {
988 if (throwOnNoConsole)
989 {
991 }
992 return default(global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO);
993 }
994 if (!global::Interop.Kernel32.GetConsoleScreenBufferInfo(outputHandle, out var lpConsoleScreenBufferInfo) && !global::Interop.Kernel32.GetConsoleScreenBufferInfo(ErrorHandle, out lpConsoleScreenBufferInfo) && !global::Interop.Kernel32.GetConsoleScreenBufferInfo(InputHandle, out lpConsoleScreenBufferInfo))
995 {
996 int lastPInvokeError = Marshal.GetLastPInvokeError();
997 if (lastPInvokeError == 6 && !throwOnNoConsole)
998 {
999 return default(global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO);
1000 }
1001 throw System.IO.Win32Marshal.GetExceptionForWin32Error(lastPInvokeError);
1002 }
1004 {
1005 _defaultColors = (byte)((uint)lpConsoleScreenBufferInfo.wAttributes & 0xFFu);
1007 }
1008 succeeded = true;
1009 return lpConsoleScreenBufferInfo;
1010 }
1011}
WindowsConsoleStream(IntPtr handle, FileAccess access, bool useFileAPIs)
Definition ConsolePal.cs:31
override int Read(Span< byte > buffer)
Definition ConsolePal.cs:45
static unsafe int ReadFileNative(IntPtr hFile, Span< byte > buffer, bool isPipe, out int bytesRead, bool useFileAPIs)
Definition ConsolePal.cs:74
override void Write(ReadOnlySpan< byte > buffer)
Definition ConsolePal.cs:56
override void Dispose(bool disposing)
Definition ConsolePal.cs:39
static unsafe int WriteFileNative(IntPtr hFile, ReadOnlySpan< byte > bytes, bool useFileAPIs)
static bool TreatControlCAsInput
static int WindowHeight
static bool IsOutputRedirectedCore()
static global::Interop.Kernel32.Color ConsoleColorToColorAttribute(ConsoleColor color, bool isBackground)
static Encoding InputEncoding
static IntPtr ErrorHandle
static volatile byte _defaultColors
static int int Top GetCursorPosition()
static bool CursorVisible
static ConsoleColor ColorAttributeToConsoleColor(global::Interop.Kernel32.Color c)
static bool IsModKey(global::Interop.InputRecord ir)
static IntPtr InvalidHandleValue
static void SetBufferSize(int width, int height)
static bool IsHandleRedirected(IntPtr handle)
static int Left
static unsafe bool ConsoleHandleIsWritable(IntPtr outErrHandle)
static int BufferHeight
static IntPtr InputHandle
static unsafe string Title
static int WindowTop
static IntPtr OutputHandle
static Stream OpenStandardInput()
static volatile bool _haveReadDefaultColors
static bool IsAltKeyDown(global::Interop.InputRecord ir)
static void SetConsoleOutputEncoding(Encoding enc)
static void EnsureConsoleInitialized()
static int LargestWindowHeight
static Stream OpenStandardError()
static unsafe void SetWindowPosition(int left, int top)
static TextReader GetOrCreateReader()
static readonly object s_readKeySyncObject
static bool KeyAvailable
static Stream GetStandardFile(int handleType, FileAccess access, bool useFileAPIs)
static int LargestWindowWidth
static bool IsErrorRedirectedCore()
static unsafe void SetWindowSize(int width, int height)
static ConsoleColor ForegroundColor
static Stream OpenStandardOutput()
static global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo(bool throwOnNoConsole, out bool succeeded)
static void ResetColor()
static void SetCursorPosition(int left, int top)
static bool NumberLock
static Encoding OutputEncoding
static bool IsInputRedirectedCore()
static void Beep()
static void Beep(int frequency, int duration)
static global::Interop.Kernel32.CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo()
static bool IsKeyDownEvent(global::Interop.InputRecord ir)
static ConsoleKeyInfo ReadKey(bool intercept)
static int BufferWidth
static int WindowLeft
static int CursorSize
static unsafe void MoveBufferArea(int sourceLeft, int sourceTop, int sourceWidth, int sourceHeight, int targetLeft, int targetTop, char sourceChar, ConsoleColor sourceForeColor, ConsoleColor sourceBackColor)
static void SetConsoleInputEncoding(Encoding enc)
static int WindowWidth
static ConsoleColor BackgroundColor
static bool CapsLock
static global::Interop.InputRecord _cachedInputRecord
static bool IsWindows7()
static void Clear()
static void Write(string format, object? arg0)
Definition Console.cs:850
static bool IsInputRedirected
Definition Console.cs:191
static Encoding InputEncoding
Definition Console.cs:69
static bool IsErrorRedirected
Definition Console.cs:219
static Encoding OutputEncoding
Definition Console.cs:99
static bool IsOutputRedirected
Definition Console.cs:205
static OperatingSystem OSVersion
static Exception GetFileNotOpen()
Definition Error.cs:5
static new readonly StreamReader Null
static readonly Stream Null
Definition Stream.cs:488
static SyncTextReader GetSynchronizedTextReader(TextReader reader)
static Exception GetExceptionForWin32Error(int errorCode, string path="")
static string ArgumentOutOfRange_NeedPosNum
Definition SR.cs:20
static string ArgumentOutOfRange_ConsoleWindowSize_Size
Definition SR.cs:16
static string ArgumentOutOfRange_ConsoleWindowPos
Definition SR.cs:66
static string ArgumentOutOfRange_BeepFrequency
Definition SR.cs:74
static string ArgumentOutOfRange_ConsoleWindowBufferSize
Definition SR.cs:14
static string InvalidOperation_ConsoleKeyAvailableOnFile
Definition SR.cs:68
static string Format(string resourceFormat, object p1)
Definition SR.cs:118
static string IO_NoConsole
Definition SR.cs:58
static string ArgumentOutOfRange_CursorSize
Definition SR.cs:72
static string InvalidOperation_ConsoleReadKeyOnFile
Definition SR.cs:60
static string ArgumentOutOfRange_ConsoleBufferBoundaries
Definition SR.cs:64
static string Arg_InvalidConsoleColor
Definition SR.cs:56
static string ArgumentOutOfRange_ConsoleBufferLessThanWindowSize
Definition SR.cs:70
Definition SR.cs:7
static Encoding GetSupportedConsoleEncoding(int codepage)
virtual int CodePage
Definition Encoding.cs:515
static readonly IntPtr Zero
Definition IntPtr.cs:18