C# 重定向输出时,为什么调整控制台缓冲区会引发无效句柄异常?

C# 重定向输出时,为什么调整控制台缓冲区会引发无效句柄异常?,c#,windows,console,stdout,handle,C#,Windows,Console,Stdout,Handle,在C#控制台应用程序中调整Console.BufferWidth会在将输出重定向到文件时引发异常。让我们调用示例test1.exe: static void Main(string[] args) { Console.BufferWidth = 240; Console.WriteLine("output1\noutput2"); } 标准输出很好: test1.exe output1 output2 重定向到文件会引发异常: test1.exe > file.txt

在C#控制台应用程序中调整Console.BufferWidth会在将输出重定向到文件时引发异常。让我们调用示例test1.exe:

static void Main(string[] args) {
    Console.BufferWidth = 240;
    Console.WriteLine("output1\noutput2");
}
标准输出很好:

test1.exe
output1
output2
重定向到文件会引发异常:

test1.exe > file.txt

Unhandled Exception: System.IO.IOException: The handle is invalid.

   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.__Error.WinIOError()
   at System.Console.SetBufferSize(Int32 width, Int32 height)
   at System.Console.set_BufferWidth(Int32 value)
   at test1.Program.Main(String[] args) in \\wopr\falken\test1\Program.cs:line 13
使用try…catch很容易忽略,但对于文件句柄或一般句柄,有一些东西我并不了解

为什么句柄无效?

重定向到文件

test1.exe > file.txt
意味着操作系统正在将应用程序的输出流从标准输出流(控制台)重定向到一个文件,这发生在进程启动时

控制台和文件都是所谓的“I/O设备”,操作系统为它们分配一个唯一的ID号,称为“句柄”。系统使用此句柄跟踪设备的属性

不同的设备具有不同的属性。控制台由其窗口直观地表示,但数据(字符)存储在其缓冲区中。窗口有其宽度和高度(请参见和属性),但也有屏幕缓冲区大小-宽度和高度(请参见和属性)。如果打开命令提示符并转到下拉菜单中的“属性”,则可以手动编辑这些属性。如果单击标题栏左角的图标,将显示下拉菜单中的“属性”

当应用程序执行时

Console.BufferWidth = 240;
它尝试更改当前输出设备(文件)不存在的属性(窗口缓冲区大小)。您的应用程序已重定向输出,它具有文件句柄和控制台。该对象不支持BufferWidth。因此,您会得到
IOException
(句柄无效)

MSDN页面,介绍如何在重定向情况下设计代码:

当底层流被激活时正常工作的控制台类成员 如果流被引导到控制台,则可能引发异常 例如,重定向到一个文件。对应用程序进行编程以捕获 如果重定向标准流,则System.IO.IOException异常。 您还可以使用IsOutputRedirected、IsInputRedirected和 IsErrorRedirected属性以确定是否为标准流 在执行引发错误的操作之前重定向 System.IO.IOException异常