Search code examples
c#windowsconsolestdouthandle

Why does adjusting console buffer raise invalid handle exception when redirecting output?


Adjusting the Console.BufferWidth in a C# console application raises an exception when redirecting output to a file. Let's call the example test1.exe:

static void Main(string[] args) {
    Console.BufferWidth = 240;
    Console.WriteLine("output1\noutput2");
}

Standard output is fine:

test1.exe
output1
output2

Redirecting to file raises exception:

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

It's easy enough to ignore using try...catch, but there's something I don't understand about file handles or handles in general.

Why is the handle invalid?


Solution

  • Redirection to file

    test1.exe > file.txt
    

    means that operating system is redirecting output stream of your application from the standard output stream (console) to a file and this happens on the process launch.

    Both console and file are so called "I/O devices" and operating system assigns to each of them a unique ID number called "handle". The system uses this handle to keep track of device's attributes.

    Different devices have different attributes. Console is visually represented by its window but the data (characters) are stored in its buffer. Window has its Width and Height (see Console.WindowWidth and Console.WindowHeight properties) but also screen buffer size - Width and Height (see Console.BufferWidth and Console.BufferHeight properties). You can edit these properties manually if open Command Prompt and go to Properties in the drop-down menu which appears if you click on the icon in the left corner of the title bar.

    When your application executes

    Console.BufferWidth = 240;
    

    it tries to change the attribute (window buffer size) which does not exist for the current output device (file). Your application has redirected output, it has a handle of a file and Console.BufferWidth is not supported on that object. Therefore you get that IOException (The handle is invalid).

    MSDN page about Console Class how to design your code in case of redirection:

    Console class members that work normally when the underlying stream is directed to a console might throw an exception if the stream is redirected, for example, to a file. Program your application to catch System.IO.IOException exceptions if you redirect a standard stream. You can also use the IsOutputRedirected, IsInputRedirected, and IsErrorRedirected properties to determine whether a standard stream is redirected before performing an operation that throws an System.IO.IOException exception.