views:

62

answers:

2

I've got a program that spawns two other proccesses using System.Diagnostics.Process. Their output is captured by the first program:

            players[p.Key].StartInfo = new ProcessStartInfo
            {
                FileName = args[i],
                RedirectStandardInput = true,
                RedirectStandardOutput = true,
                UseShellExecute = false
            };

I'm trying to debug these sub-proccesses. Debug.WriteLine works from the main program, but it isn't captured when called from within the sub-processes. How can I get it to work?

Is there a way to "redirect" that too? Or to open an output window in VS for the sub-proccesses?

+3  A: 

You can can capture all the Debug.WriteLine output from every process with DbgView ( http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx ).

You can filter/highlight by process too, which might be helpful.

Actually, that probably won't capture the process which VS is actually debugging, so you'll get your top level process trace in VS and your other processes in DbgView, which might work out nicely.

Another potentially useful technique during development (or on systems where the ugly console window doesn't matter) is to redirect the trace output to a console like this:

Trace.Listeners.Add(new ConsoleTraceListener())

You can add a console to any application by calling AllocConsole(), which you'll need to p/invoke, by adding the following declaration to your code:

using System.Runtime.InteropServices;

[DllImport("kernel32.dll", SetLastError = true)]
static extern void AllocConsole();

See: http://msdn.microsoft.com/en-us/library/system.diagnostics.consoletracelistener.aspx

Will Dean
Beware that `Debug.Xxx` methods are conditional on the DEBUG symbol. Hence, they won't be present in release builds. This is not true of `Trace.Xxx` methods, so perhaps that would be a more appropriate API for the OP.
Kent Boogaart
Wow, that's a really handy program. I'm surprised it just works out of the box like that!
Mark
@Kent: Ah! Didn't know the difference between `Debug` and `Trace`, but `Debug` is just fine, as that's what I'm doing ;)
Mark
And beware that the Trace.xxxx methods are conditional on the TRACE symbol (that just tripped me up in a quick command-line CSC compile)
Will Dean
+1  A: 

You can also add a config file to the exe file of your child processes to create a TextWriterTraceListener and write all log messages of that exe to a log file:

<configuration>
    <system.diagnostics>
        <trace autoflush="true" indentsize="4">
            <listeners>
                <add name="TextListener" 
                    type="System.Diagnostics.TextWriterTraceListener"
                    initializeData="trace.log" />
            <remove name="Default" />
            </listeners>
        </trace>
    </system.diagnostics>
</configuration>

If the program is named myapp.exe then the name of the config file needs to be myapp.exe.config and the config file needs to be placed in the same folder as the exe in order to be picked up.

Please also note that output created with the methods in the System.Diagnostics.Debug namespace only is available in a Debug build. If you want to create trace messages also in the Release build you can use the equivalent WriteLine method from the System.Diagnostics.Trace namespace.

Both Trace.WriteLine and Debug.WriteLine actually call the same Windows API method under the hood: OutputDebugString. You are also able to directly attach globally to the output of such method calls from your .NET application. An article on CodeProject describes the necessary steps in detail:

DbMon.NET - A simple .NET OutputDebugString capturer

0xA3