Is it possible to redirect standard output to the output window from Visual Studio?
I use OutputDebugString in my program, but I use some libraries that
I was using Visual Studio 2012 and also wanted to redirect standard output and standard error while debugging a script, a C++ program or a MSTest DLL without having to change the source code itself. My approach, that I finally came up with, was to capture the output using sort of an intermediate program.
Take the following C# code and create/compile a Windows C# .NET Console Application:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
namespace OutputDebugStringConsole
{
class OutputDebugStringConsole
{
private static void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (null != outLine.Data)
{
Trace.WriteLine(outLine.Data);
Trace.Flush();
Console.WriteLine(outLine.Data);
}
}
static void Main(string[] args)
{
if (args.Length == 0)
{
return;
}
try
{
Process p = new Process();
p.StartInfo.FileName = args[0];
p.StartInfo.Arguments = String.Join(" ", args, 1, args.Length - 1);
Trace.WriteLine("Calling " + p.StartInfo.FileName + " " + p.StartInfo.Arguments);
p.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
p.StartInfo.CreateNoWindow = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
p.ErrorDataReceived += new DataReceivedEventHandler(OutputHandler);
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
// Call WaitForExit() AFTER I know the process has already exited by a successful return from WaitForExit(timeout).
// This causes the code that reads all remaining pending async data to be executed.
// see https://groups.google.com/d/msg/microsoft.public.dotnet.framework.sdk/jEen9Hin9hY/FQtEhjdKLmoJ
Thread.Sleep(100);
p.WaitForExit();
p.Close();
}
catch (Exception e)
{
Trace.WriteLine(e.ToString());
Console.WriteLine("{0} Exception caught.", e);
}
}
}
}
I used Trace.WriteLine() instead of Debug.WriteLine(), because it then works also in the release version of the above code.
NOTE: If you have chosen .NET 4/4.5 and you are capturing the output of unmanaged code, you need to select Mixed as your Debugging/Debugger Type in your Project Settings. Otherwise (with Auto) you may get an unhandled KernelBase.dll exception.
Now you can use the application by putting the newly created
OutputDebugStringConsole.exe
into Debugging/Command properties and
"$(TargetPath)" [ARGS ...]
or e.g. if it is the MSTest DLL file:
"$(DevEnvDir)CommonExtensions\Microsoft\TestWindow\vstest.console.exe" /Platform:x86 $(TargetPath)
into your Debugging/Arguments of the application you want to debug. The quotation marks in the command arguments are necessary to handle spaces in your application's path.
Please take this only as an example what the application can be used for. I'm aware that the Visual Studio 2012 Test Explorer does offer a very nice way to run MSTest DLL files and get the output in a structured way.