How do I control where Debug.WriteLine debug output goes in C#?

If you’re running your program in the Visual Studio debugger, and you’ve built it in debug mode (the DEBUG build flag is set), you’ll see the output from System.Diagnostics.Debug.WriteLine (and related debug output functions) in the Output window in Visual Studio (typically configured as a tabbed area at the bottom of the Visual Studio window. You can enable the Output window using View | Output. You can quickly switch to the Output window using CTRL-ALT-O (assuming you haven’t changed the default keyboard shortcuts).

Now, debug output may not display in the Output window if you have the Visual Studio option “Redirect all Output Window text to the Immediate Window” checked under Tools | Options | Debugging | General. In this case, debug output will appear in the Immediate window. You can enable the Immediate window using Debug | Windows | Immediate. You can quickly switch to the Immediate window using CTRL-ALT-I (assuming you haven’t changed the default keyboard shortcuts).

The System.Diagnostics.Debug.Listeners property gives you the list of TraceListeners that are monitoring debug output. By default, there is just one entry in this list: System.Diagnostics.DefaultTraceListener. If you want to remove this default listener, you can use the Remove method on the System.Diagnostics.Debug.Listeners collection.

If you’d like to capture/direct the debug output elsewhere, just establish a TraceListener, and add it to the System.Diagnostics.Debug.Listeners collection. For example, to see debug output on the console in a console application, you could say:

TextWriterTraceListener myListener = new TextWriterTraceListener(System.Console.Out);

From this point onward, you’ll see debug output appear on the application’s console. If you want to send the debug output to a text file, just create a TraceListener for the destination file and add that to Debug.Listeners:

TextWriterTraceListener myListener = new TextWriterTraceListener("myDebugLogFile.txt"));

Of course, by adding multiple TraceListener objects to Debug.Listeners, you can record debug output in multiple places.

If you’re worried about not missing anything in the debug output, and you’re willing to pay the potential performance penalty, you can set System.Diagnostics.Debug.AutoFlush to true. This will cause a Flush to be performed on every debug output TraceListener after each output operation. The default value of this property is false.

The same goes for output from System.Diagnostics.Trace output methods, assuming the TRACE build flag is set.
DEBUG and TRACE build flags are easily set within Visual Studio. If you’re using the command-line tools, just add /define:DEBUG to set the debug flag, /define:TRACE to set the TRACE flag, or /define:DEBUG;TRACE to set both flags.