I wrote a utility originally with Windows 7, which reads the entire console buffer and creates a text file with its contents. A stripped down version (no filing) is shown below, compiled as 32-bit with MSVC 2022.
On that machine the console buffer has 300 lines. The program outputs the following:
width = 80 depth = 300 buflen = 24000 nread = 24000
Now, on a Windows 11 machine the console buffer is about 9000 lines, which can be verified by scrolling up. Yet only the current viewport is captured, and the output here is:
width = 80 depth = 25 buflen = 2000 nread = 2000
I tried requesting more bytes to be read, but nread
is still 2000. I’ve tried both GetConsoleScreenBufferInfo()
and GetConsoleScreenBufferInfoEx()
which give the same result.
Microsoft warns that ReadConsoleOutputCharacter should no longer be used, but is still supported. I also tried the sample code given by Scrolling a Screen Buffer’s Window. This carries a similar warning, and again it works on Windows 7 but not on Windows 11.
The warnings advise using virtual terminal control sequences, but I don’t see how they can be used to read the buffer.
How does one read the contents of the whole console buffer in Windows 11? Is it restricted by tighter security?
#define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
void fail(const char *msg) {
printf("%sn", msg);
exit(1);
}
int main(void) {
// fill the console buffer
for(int i = 10000; i > 0; i--)
printf("%dn", i);
fflush(stdout);
// get the console handle
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
if(hConsole == INVALID_HANDLE_VALUE)
fail("Unable to get console handle");
// get the console sizing
CONSOLE_SCREEN_BUFFER_INFO info = {0};
if(!GetConsoleScreenBufferInfo(hConsole, &info))
//CONSOLE_SCREEN_BUFFER_INFOEX info = { sizeof(CONSOLE_SCREEN_BUFFER_INFOEX) };
//if (!GetConsoleScreenBufferInfoEx(hConsole, &info))
fail("Cannot get console size");
size_t width = info.dwSize.X;
size_t depth = info.dwSize.Y;
// allocate memory
size_t buflen = width * depth;
LPTSTR buf = malloc(buflen);
if(buf == NULL)
fail("Cannot allocate buffer memory");
// collect the console buffer
COORD coord = {0, 0};
DWORD nread = 0;
if(!ReadConsoleOutputCharacter(hConsole, buf, buflen, coord, &nread))
fail("Cannot read console buffer");
// results
printf("width = %zun", width);
printf("depth = %zun", depth);
printf("buflen = %zun", buflen);
printf("nread = %zun", (size_t)nread);
// output to file . . . removed
free(buf);
return 0;
}
3