Simon Laing
Simon Laing

Reputation: 1214

.NET console output bypassing redirection

The Console class in .NET supports writing text to standard output and standard error. However, I believe there is another stream that can be written to, that cannot be redirected.

See Display & Redirect Output

A batch file could achieve this like so:

echo hello > CON

How could this stream, or the effect non-redirectable output, be achieved in C#?

Upvotes: 0

Views: 85

Answers (1)

Simon Laing
Simon Laing

Reputation: 1214

Thanks to Hans Passant, the following solution works (with a graceful fallback to Console.Out if the CONOUT$ 'file' could not be created):

public static class Progress
{
    private static readonly TextWriter _writer;

    [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern IntPtr CreateFile(
         [MarshalAs(UnmanagedType.LPTStr)] string filename,
          uint fileAccess,
         [MarshalAs(UnmanagedType.U4)] FileShare share,
         IntPtr securityAttributes, // optional SECURITY_ATTRIBUTES struct or IntPtr.Zero
         [MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
         [MarshalAs(UnmanagedType.U4)] FileAttributes flagsAndAttributes,
         IntPtr templateFile);

    const int FILE_ACCESS_WRITE = 0x40000000;

    static Progress()
    {
        var realStdOut = new SafeFileHandle(CreateFile("CONOUT$", FILE_ACCESS_WRITE, FileShare.ReadWrite, IntPtr.Zero, FileMode.OpenOrCreate, 0, IntPtr.Zero), true);

        _writer = !realStdOut.IsInvalid
            ? new StreamWriter(new FileStream(realStdOut, FileAccess.Write))
            : Console.Out;
    }

    public static void WriteLine(string format, params object[] args)
    {
        _writer.WriteLine(format, args);
        _writer.Flush();
    }
}

Sometimes when debugging the app via Visual Studio I found that it failed to create the CONOUT$ file - hence the graceful fallback.

Upvotes: 1

Related Questions