В образовательных целях в университете я занимаюсь разработкой модульного приложения 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, потому что это на самом деле ярлык, не указывающий на исполняемый файл, поэтому я не смог извлечь из этого пользу.
Любая помощь будет оценена! Спасибо! 🙂
Задача ещё не решена.
Других решений пока нет …