For educational purposes at the university, I am developing a modular WCF C# application. The client app sends a source, the server takes care of compiling, testing and returning a result to the client.
One of the modules of the server does the compiling job. It consumes the source and produces an EXE to be used by the other module(s).
My problem is: when invoking cl.exe
for the case when the given source is written in C++, I manage to compile it, but the compiling module cannot receive the error messages properly from the child process, that runs cmd.exe
, which then starts cl.exe
. The source code and an example of what actually happens say more than a million words, so here they are:
public static string clPath = @"E:\path_to_project\Client\clTo4kaEXE\";
string sourceCode = "//given source";
using (StreamWriter sw = new StreamWriter(clPath + exeName + ".cpp"))
{
sw.Write(sourceCode);
sw.Flush();
}
Process clTo4kaEXE = new Process();
clTo4kaEXE.StartInfo.FileName = clPath + "cmd.exe";
clTo4kaEXE.StartInfo.WorkingDirectory = clPath;
clTo4kaEXE.StartInfo.UseShellExecute = false;
clTo4kaEXE.StartInfo.RedirectStandardOutput = true;
clTo4kaEXE.StartInfo.RedirectStandardError = true;
clTo4kaEXE.StartInfo.RedirectStandardInput = true;
clTo4kaEXE.StartInfo.Arguments = "%comspec% /k \"\"e:\\vs2010\\VC\\vcvarsall.bat\"\" x86";
clTo4kaEXE.Start();
clTo4kaEXE.StandardInput.WriteLine("cl /EHsc " + exeName + ".cpp");
StreamReader clStandardOutput = clTo4kaEXE.StandardOutput;
StreamReader clErrorOutput = clTo4kaEXE.StandardError;
string clStdOutput = "";
string temp = "";
while(true)
{
//Debugger.Launch(); // breakpoint
temp = clStandardOutput.ReadLine();
Console.WriteLine("STD TEMP = {0}", temp);
clStdOutput += temp;
//if (temp == null /*|| temp == "" */|| clStandardOutput.EndOfStream)
//{
// break;
//}
if (clStandardOutput.Peek() == -1 && temp == "")
{
break;
}
}
string clErrOutput = "";
temp = "";
while (true)
{
temp = clErrorOutput.ReadLine();
Console.WriteLine("ERROR TEMP = {0}", temp);
clErrOutput += temp;
//if (temp == null || temp == "" || clErrorOutput.EndOfStream)
//{
// break;
//}
if (clErrorOutput.Peek() == -1 && temp == "")
{
break;
}
}
clTo4kaEXE.Close();
Console.WriteLine("[Modul_Compile] cl.exe returned on its standard output: {0}\n", clStdOutput);
Console.WriteLine("[Modul_Compile] cl.exe returned on its error output: {0}\n", clErrOutput);
When there is an error in the source, for example missing ';' somewhere, then here is what i see in the console:
Then I decided to run Visual Studio Command Prompt giving it the same source code and here is what i get:
Remarks:
clStdOutput= clStandardOutput.ReadToEnd();
used instead of thatwhile(true){}
causes the client app's window to "freeze" and the compiling module doesn't receive anything from its child process.I am pretty surprised that
cl.exe
prints the messages "Microsoft (R) 32-bit C/C++ Optimizing..." and "Copyright (C)... All rights reserved." to its Error output - the stream, from which I expect to receive the compiling error.I searched the net for any info, found some clues, which helped me get anything from the child process. Now the next step is to get what i need to.
I couldn't find a way to start the VS Command Prompt, because it's actually a shortcut, not pointing to an exe, so I couldn't benefit from it.
Any help would be appreciated! Thanks! :)