public static IEnumerable <string> ReadFromBuffer(short x, short y, short width, short height) { IntPtr buffer = Marshal.AllocHGlobal(width * height * Marshal.SizeOf(typeof(CHAR_INFO))); if (buffer == null) { throw new OutOfMemoryException(); } try { var coord = new Coord(); var rc = new SmallRect { Left = x, Top = y, Right = (short)(x + width - 1), Bottom = (short)(y + height - 1) }; var size = new Coord { X = width, Y = height }; const int STD_OUTPUT_HANDLE = -11; if (!ReadConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE), buffer, size, coord, ref rc)) { // 'Not enough storage is available to process this command' may be raised for buffer size > 64K (see ReadConsoleOutput doc.) throw new Win32Exception(Marshal.GetLastWin32Error()); } IntPtr ptr = buffer; for (int h = 0; h < height; h++) { var sb = new StringBuilder(); for (int w = 0; w < width; w++) { var ci = (CHAR_INFO)Marshal.PtrToStructure(ptr, typeof(CHAR_INFO)); char[] chars = Console.OutputEncoding.GetChars(ci.charData); sb.Append(chars[0]); ptr += Marshal.SizeOf(typeof(CHAR_INFO)); } yield return(sb.ToString()); } } finally { Marshal.FreeHGlobal(buffer); } }
private static extern bool ReadConsoleOutput(IntPtr hConsoleOutput, IntPtr lpBuffer, Coord dwBufferSize, Coord dwBufferCoord, ref SmallRect lpReadRegion);