Redirecting Standard Error for a .NET application

A while back I was working on a small Proof of concept where I needed to use console based client to connect to a server and use it to send and receive messages to other clients.As you must be aware of that all windows process are attached with a standard error ,input and output streams.Input stream by default point to keyboard and in case of a console application both standard error and output stream point to console.That means any program related output and exceptions are by default displayed in console window.That was problematic for me as couple of third party dlls and framework which I was using had extensive logging on errors and both the output and error were getting terribly mixed up.Most of these errors were not fatal errors and were not supposed to close the application e.g. whenever client and server TCP connection was lost an exception was raised and used to come in red font on console window.

Solution was to redirect error stream to something other than console and let only valid output be displayed on console.

Redirection in case of a child process

By child process I just mean one process spawning another process.It is quite simple in case you want to start a child process and want its output or errors to be redirected i.e. you have a console application (or any kind of application for that matter) and you start another process from it and redirect its error to a file.

var childProcess = new Process();
childProcess.StartInfo.FileName = "ChildProcess.exe";
childProcess.StartInfo.UseShellExecute = false;
childProcess.StartInfo.RedirectStandardError = true;
childProcess.Start();
using (StreamReader reader = childProcess.StandardError)
{
    string result = reader.ReadToEnd();
   //WRITE TO A FILE OR TO ANY OTHER TARGET
}
childProcess.WaitForExit();

 

You need to make sure that UseShellExecute = false as it makes sure that process is started as a child process.In case it is true, process would be started using windows shell and would be assigned its own standard error and output (we would deal with this in the next section).In such cases reading from StandardError stream throws exception.

This whole thing was not useful for me as I wanted to redirect the error stream of my top level console process (i.e. there was only one process and no parent spawning child).

Redirection in case of a top level process

By top level process I mean a process started by windows shell (i.e. the ones we start by double clicking a .exe file).Console.SetErorr method in Console class seems to do something similar.Basically it takes a TextWriter and makes that new standard error.At first look it seems we got our solution but that is not the case.It just writes anything written specifically to Console.Error stream (e.g. using Console.Error.Write) to the redirected stream but any exceptions coming from your code or third party dlls will still go to Console.

After struggling a little I realized that there is NO direct way of doing this using .NET framework libraries (In case any of you know a way,  let me know ).So how do we do this ?

Answer is to do this via PInvoke to SetStdHandle windows kernel32.dll method.So in case you want to totally redirect all your errors use something like below.

[DllImport("Kernel32.dll", SetLastError = true)]
public static extern int SetStdHandle(int device, IntPtr handle);

public static void RedirectStandardErrorToFile(FileStream fileStream)
{
    StreamWriter errStream = new StreamWriter(fileStream);
    errStream.AutoFlush = true;
    Console.SetError(errStream);
    var status = SetStdHandle(-12, fileStream.SafeFileHandle.DangerousGetHandle()); // set stderr
}

SetStdHandle first parameter specifies which stream to redirect i.e. –12 is for stderr and –11 for stdout.Notice that we also use same stream in Console.SetError.

Also all this applies in case you want to redirect standard output or both.

One disadvantage of using this is that you application is now tied to windows platform i.e. you cannot use it with for example with mono on Linux.

Also, If you are someone extensively working on .NET console applications or are interested to know more than just the basics than there is an excellent pluralsight course on building console application in .NET which you might want to look into.

Tagged on: , , ,

One thought on “Redirecting Standard Error for a .NET application

  1. youtube0mp3

    While, I am able to redirect the standard output to a file, I am having trouble with routing the output to a text box.

Leave a Reply to youtube0mp3 Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.