出于大学教育的目的,我正在开发一个模块化的 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-bit C/C++ Optimizing...”和“Copyright (C)...All rights reserved.”让我感到非常惊讶。到它的错误输出 - 我希望从中接收编译错误的流。我在网上搜索了任何信息,发现了一些线索,这有助于我从子进程中获取任何信息。现在下一步是得到我需要的东西。
我找不到启动 VS 命令提示符的方法,因为它实际上是一个快捷方式,而不是指向 exe,所以我无法从中受益。
任何帮助,将不胜感激!谢谢!:)