Как получить ошибки компиляции, возвращаемые из cl.exe
В образовательных целях в университете я занимаюсь разработкой модульного приложения WCF C#. Клиентское приложение отправляет источник, сервер заботится о компиляции, тестировании и возврате результата клиенту.
Один из модулей сервера выполняет работу по компиляции. Он потребляет источник и создает EXE-файл, который будет использоваться другим модулем.
Моя проблема: при вызове cl.exe
для случая, когда данный источник написан на C++, мне удается скомпилировать его, но модуль компиляции не может правильно получать сообщения об ошибках от дочернего процесса, который запускается cmd.exe
, который затем начинается cl.exe
, Исходный код и пример того, что на самом деле происходит, говорят более миллиона слов, поэтому вот они:
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);
Когда в источнике есть ошибка, например отсутствует ';' где-то, то вот что я вижу в консоли:
Затем я решил запустить командную строку Visual Studio с тем же исходным кодом, и вот что я получил:
Примечания:
clStdOutput= clStandardOutput.ReadToEnd();
используется вместо этогоwhile(true){}
вызывает "зависание" окна клиентского приложения, и модуль компиляции не получает ничего от своего дочернего процесса.Я очень удивлен, что
cl.exe
печатает сообщения "Microsoft (R) 32-разрядная оптимизация C/C++..." и "Авторское право (C)... Все права защищены". к его выводу Error - поток, от которого я ожидаю получить ошибку компиляции.Я искал в сети любую информацию, нашел некоторые подсказки, которые помогли мне получить что-нибудь от дочернего процесса. Теперь следующий шаг - получить то, что мне нужно.
Я не смог найти способ запустить командную строку VS, потому что это на самом деле ярлык, не указывающий на исполняемый файл, поэтому я не смог извлечь из этого пользу.
Любая помощь будет оценена! Спасибо!:)