奇怪的控制台 MoveBufferArea IOException

发布于 2024-08-13 18:40:34 字数 874 浏览 3 评论 0原文

我正在构建一个“反向控制台”(以便写入的行会附加在顶部而不是底部),因为我偶然发现了 Console.MoveBufferArea 方法的一个非常奇怪的行为:

    static void Main()
    {
        for (var _linesWritten = 0; _linesWritten < 1000; _linesWritten++)
        {
            var _height = Math.Min(Console.BufferHeight-1, _linesWritten);
            Console.MoveBufferArea(0, 0, Console.BufferWidth, _height, 0, 1);
            Console.SetCursorPosition(0, 0);
            Console.WriteLine("Line {0} aaaaaaaaaa", _linesWritten);
            Console.ResetColor();
        }
    }

当我调用它固定次数时,它抛出 System.IO.IOException 并指出:“没有足够的存储空间来处理此命令”。我发现这取决于移动的缓冲区数量。当我更改 Console.BufferWidth 属性时,抛出异常之前写入的行数会发生变化。

屏幕截图

我运行的是 Windows 7 x64 @ Corei7,6gb DDR3 ,所以存储不应该是问题...... 有人知道可能出了什么问题吗?

I was building a "reverse console" (so that the written lines would append themselves on the top instead of the bottom) as I stumbled upon a very strange behavior of the Console.MoveBufferArea method:

    static void Main()
    {
        for (var _linesWritten = 0; _linesWritten < 1000; _linesWritten++)
        {
            var _height = Math.Min(Console.BufferHeight-1, _linesWritten);
            Console.MoveBufferArea(0, 0, Console.BufferWidth, _height, 0, 1);
            Console.SetCursorPosition(0, 0);
            Console.WriteLine("Line {0} aaaaaaaaaa", _linesWritten);
            Console.ResetColor();
        }
    }

When i call it a fixed number of times it throws an System.IO.IOException saying: "Not enough storage is available to process this command". I figured out that it depends on the amount of the buffer area being moved around. The number of lines written before the exception is thrown changes as I change the Console.BufferWidth property.

Screenshot

I am running Windows 7 x64 @ Corei7, 6gb DDR3, so storage shuldn't be the problem....
Does anybody have a clue what could be wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

晚风撩人 2024-08-20 18:40:34

导致异常的API函数是ReadConsoleOutput()。 SDK 文档有一些相关的小字:

lpBuffer:

指向目标缓冲区的指针
接收从读取的数据
控制台屏幕缓冲区。这个指针是
被视为原点
CHAR_INFO 的二维数组
其大小由以下指定的结构
dwBufferSize 参数。总计
数组的大小必须小于
64K

我将相关短语加粗。当你的程序尝试滚动超过 200 行(201 x 80 x 4 = 64320 字节,奇怪的是,与 65536 相比有点偏离)时,它就会崩溃。这可以说是 Console.MoveBufferArea() 中的一个错误,它不会检查此限制,也不会尝试解决它,这很容易做到。您可以在 connect.microsoft.com 上报告该错误。

目前,您必须限制行数,以便缓冲区大小不超过限制。

The API function that causes the exception is ReadConsoleOutput(). The SDK doc has some relevant small print:

lpBuffer:

A pointer to a destination buffer that
receives the data read from the
console screen buffer. This pointer is
treated as the origin of a
two-dimensional array of CHAR_INFO
structures whose size is specified by
the dwBufferSize parameter. The total
size of the array must be less than
64K
.

I bolded the relevant phrase. Your program will bomb when it tries to scroll more than 200 lines (201 x 80 x 4 = 64320 bytes, oddly off a bit from 65536). It is arguably a bug in the Console.MoveBufferArea(), it doesn't check for this limitation nor tries to work around it which would be easy to do. You can report the bug at connect.microsoft.com

For now, you'll have to limit the number of lines so the buffer size doesn't exceed the limit.

请恋爱 2024-08-20 18:40:34

控制台不仅仅是另一个窗口。它的真正目的是允许双向输入、shell 级重定向等,并且当您尝试执行此类操作时可能会出现一些奇怪的问题。这主要是因为您正在使用文件流缓冲区,而不仅仅是屏幕上的文本。

您是否考虑过制作一个窗口来托管您的“控制台”信息,因为您显然正在执行非标准输出流?您可以将控制台 I/O 重定向到您自己的流(这里是在 VB.NET 中执行此操作的示例),并使用 RichTextBox 等工具将其显示在自己的窗口中。

如果您正在使用“反向”控制台,则显然您没有使用命令行重定向工具或输入机制 - 在这种情况下,自定义窗口可能是更好的方法。

The Console is not just another Window. It's really intended to allow bi-directional input, shell level redirection, etc, and can have some odd issues when you try to do things like this. This is mainly due to the fact that you're working with file stream buffers, not just text on a screen.

Have you considered just making a Window to host your "console" information, since you're obviously doing a non-standard output stream? You could just redirect your Console I/O to your own stream (here is a sample of doing this in VB.NET), and display this in a window yourself, using something like a RichTextBox.

If you're doing a "reversed" console, you're obviously not using the command line redirection facilities, or input mechanisms - in which case a custom window is probably a nicer approach.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文