Nippysaurus
Nippysaurus

Reputation: 20378

Check if output is redirected

I have a console application written in C# which processes some data then prints the results. Until the results are available there is a little animation ( / - \ | ) and progress percentage ( xx% ) which is constantly updating.

Obviously if the user redirects the output of my application this will be printed to the text file where output is redirected to. If possible I would like to avoid this.

So is there a way to detect if the output of my application is redirected? I am considering only showing the progress indicators when run with a specified parameter, but I'm hoping someone will have a good answer for me.

Upvotes: 13

Views: 4820

Answers (7)

Matt Brooks
Matt Brooks

Reputation: 1604

From .NET Framework 4.5 onwards you can use the Console.IsOutputRedirected property to detect this.

There's also Console.IsErrorRedirected.

Upvotes: 16

Matthew Scharley
Matthew Scharley

Reputation: 132284

You can't. Redirected output is totally and wholly outside the scope of the executing program. You can however add a commandline option to disable your pretty output so that it can be used redirected too.

EDIT: You CAN (now)... with .NET 4.5 onwards (see Matt Brooks' answer).

Upvotes: 2

AyrA
AyrA

Reputation: 863

Console.Write("whatever") (and WriteLine) actually write data to the stream behind Console.Out. To always show a progress bar on the console and not write it to a file, no matter if the output is redirected to a file or not, use the error stream instead:

Console.Error.Write("<your progress bar>");

When an application redirects output with the > operator (DIR C:\*.*>MORE), only Console.Out is redirected and not Console.Error

Upvotes: 0

Elliott
Elliott

Reputation: 141

Probably, you can try this:

public enum FileType : uint
{
    FILE_TYPE_UNKNOWN = 0x0000,
    FILE_TYPE_DISK = 0x0001,
    FILE_TYPE_CHAR = 0x0002,
    FILE_TYPE_PIPE = 0x0003,
    FILE_TYPE_REMOTE = 0x8000,
}

public enum STDHandle : uint
{
    STD_INPUT_HANDLE = unchecked((uint)-10),
    STD_OUTPUT_HANDLE = unchecked((uint)-11),
    STD_ERROR_HANDLE = unchecked((uint)-12),
}

[DllImport("Kernel32.dll")]
static public extern UIntPtr GetStdHandle(STDHandle stdHandle);
[DllImport("Kernel32.dll")]
static public extern FileType GetFileType(UIntPtr hFile);

static public bool IsOutputRedirected()
{
    UIntPtr hOutput = GetStdHandle(STDHandle.STD_OUTPUT_HANDLE);
    FileType fileType = (FileType)GetFileType(hOutput);
    if (fileType == FileType.FILE_TYPE_CHAR)
        return false;
    return true;
}

If the standard output is not redirected, the output of the GetFileType() should be 0x0002. This works for me. :)

Upvotes: 2

konrad.kruczynski
konrad.kruczynski

Reputation: 47571

As it turns out, it soon will be available in the elegant and cross-platform way: link.

Upvotes: 7

Stobor
Stobor

Reputation: 45132

You can use the native method GetConsoleMode to see if stdout is going to a console or not.

This method is suggested by the remarks in the documentation for WriteConsole:

... determine whether the output handle is a console handle (one method is to call the GetConsoleMode function and check whether it succeeds)...

Upvotes: 6

DocMax
DocMax

Reputation: 12164

Rather than trying to determine whether or not the content is redirected, I would use Console.WriteLine (or Console.Out.WriteLine) to print your results and Console.Error.Write for your status updates. The screen output will show properly but not be reflected in the text file.

Upvotes: 3

Related Questions