Search code examples
.netconsoleio-redirection

.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#?


Solution

  • 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.