Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I determine whether Console.Out has been redirected to a file?

Tags:

c#

.net

console

If my program is printing to the console, I perform word-wrapping in a certain way according to Console.WindowWidth by inserting newlines - and this works perfectly.

However if the output of the program is redirected to a file or another program I would like it to skip the word-wrapping. How can I detect when this is the case?

Console.WindowWidth returns the same number in both cases.

Bonus points if the solution can distinguish redirected Console.Out from redirected Console.Error.

like image 838
Roman Starkov Avatar asked Apr 13 '09 13:04

Roman Starkov


4 Answers

.NET 4.5 adds Console.IsOutputRedirected and Console.IsErrorRedirected.

like image 178
Roger Lipscombe Avatar answered Nov 12 '22 06:11

Roger Lipscombe


p/invoke GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)), or call an innocuous console function like GetConsoleScreenBufferInfo to check for invalid handle error. If you want to know about standard error, use STD_ERROR_HANDLE. I believe you can even compare handles returned by GetStdHandle(STD_OUTPUT_HANDLE) and GetStdHandle(STD_ERROR_HANDLE) to detect stuff like 2>&1.

like image 24
Anton Tykhyy Avatar answered Nov 12 '22 06:11

Anton Tykhyy


While this is a little shady and probably isn't guaranteed to work, you can try this:

bool isRedirected;

try
{
    isRedirected = Console.CursorVisible && false;
}
catch
{
    isRedirected = true;
}

Calling CursorVisible throws an exception when the console is redirected.

like image 8
Adam Robinson Avatar answered Nov 12 '22 06:11

Adam Robinson


You need to use reflection - a bit grubby but the following will work:

static bool IsConsoleRedirected()
{
    var writer = Console.Out;
    if (writer == null || writer.GetType ().FullName != "System.IO.TextWriter+SyncTextWriter") return true;
    var fld = writer.GetType ().GetField ("_out", BindingFlags.Instance | BindingFlags.NonPublic);
    if (fld == null) return true;
    var streamWriter = fld.GetValue (writer) as StreamWriter;
    if (streamWriter == null) return true;
    return streamWriter.BaseStream.GetType ().FullName != "System.IO.__ConsoleStream";
}
like image 2
Joe Albahari Avatar answered Nov 12 '22 06:11

Joe Albahari