Invoking the VS C++ compiler from a C# application
-
From within a C# application, I would like to invoke the Visual Studio command-line C++ compiler (cl.exe) to compile a simple console program (e.g., helloworld.cpp). The compiler messages should be redirected or captured to a text file. I know the environment variables have to be set (using vcvars32.bat), but I have not had any luck in hitting on the correct sequencing and parameters for System.Diagnostics.Process methods, or the Process.StartInfo property settings. I think I'm in generally the right ball park--but maybe not. Can anyone help? Thanks so much, Tom
-
From within a C# application, I would like to invoke the Visual Studio command-line C++ compiler (cl.exe) to compile a simple console program (e.g., helloworld.cpp). The compiler messages should be redirected or captured to a text file. I know the environment variables have to be set (using vcvars32.bat), but I have not had any luck in hitting on the correct sequencing and parameters for System.Diagnostics.Process methods, or the Process.StartInfo property settings. I think I'm in generally the right ball park--but maybe not. Can anyone help? Thanks so much, Tom
I tried the following and got it working without any problems (using VS2005). I also tried it in a graphical application, storing the output in a multiline-textbox instead, without any problems. Good luck!
static void Main()
{
ProcessStartInfo psi = new ProcessStartInfo("cl.exe", " -GX c:\\hello.cpp");
psi.CreateNoWindow = true;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
Process p = new Process();
p.StartInfo = psi;
p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
p.Start();
p.BeginErrorReadLine();
string sout = p.StandardOutput.ReadToEnd();
p.WaitForExit();
StringBuilder builder = new StringBuilder();
builder.AppendLine("Error:");
foreach (String s in errData)
{
builder.AppendLine(s);
}
builder.AppendLine("Output:");
builder.AppendLine(sout);Console.WriteLine(builder.ToString()); Console.WriteLine("Press ENTER to continue"); Console.ReadKey(true);
}
private static List errData = new List();
static void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
errData.Add(e.Data);
}Internet - the worlds biggest dictionary
-
I tried the following and got it working without any problems (using VS2005). I also tried it in a graphical application, storing the output in a multiline-textbox instead, without any problems. Good luck!
static void Main()
{
ProcessStartInfo psi = new ProcessStartInfo("cl.exe", " -GX c:\\hello.cpp");
psi.CreateNoWindow = true;
psi.RedirectStandardError = true;
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
Process p = new Process();
p.StartInfo = psi;
p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived);
p.Start();
p.BeginErrorReadLine();
string sout = p.StandardOutput.ReadToEnd();
p.WaitForExit();
StringBuilder builder = new StringBuilder();
builder.AppendLine("Error:");
foreach (String s in errData)
{
builder.AppendLine(s);
}
builder.AppendLine("Output:");
builder.AppendLine(sout);Console.WriteLine(builder.ToString()); Console.WriteLine("Press ENTER to continue"); Console.ReadKey(true);
}
private static List errData = new List();
static void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
errData.Add(e.Data);
}Internet - the worlds biggest dictionary
Thanks so much for your response! Wow, I'm impressed! Unfortunately it didn't work for me. It appears that the appropriate environment variables have to be set. When running from within VS2005 I had to provide the whole path to cl.exe. Even then, nothing appeared after your Error: and Output: lines. When running outside the IDE, the program complained about not being able to find mspdb80.dll. Do you know which environmental variables should be set up [programmatically], if that is indeed the problem? Thanks again, Tom
-
Thanks so much for your response! Wow, I'm impressed! Unfortunately it didn't work for me. It appears that the appropriate environment variables have to be set. When running from within VS2005 I had to provide the whole path to cl.exe. Even then, nothing appeared after your Error: and Output: lines. When running outside the IDE, the program complained about not being able to find mspdb80.dll. Do you know which environmental variables should be set up [programmatically], if that is indeed the problem? Thanks again, Tom
Sorry, no. That is a question you should ask in the C++ forum instead, since it is compiling C++ you have problems with, right?
Internet - the worlds biggest dictionary
-
Sorry, no. That is a question you should ask in the C++ forum instead, since it is compiling C++ you have problems with, right?
Internet - the worlds biggest dictionary
Well, yes and no, but certainly thanks for setting me on the right path. With some experimentation I came up with a successful C# handler (based on your code, but with necessary environment variables set--and with directories hard coded for my computer) for a "compile and run" button as follows: //////////////////////////// protected void CompileAndRun_Click(object sender, EventArgs e) { // Set up environment Environment.SetEnvironmentVariable("INCLUDE", @"C:\Program Files\Microsoft Visual Studio 8\VC\ATLMFC\INCLUDE;C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE;C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include;C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\include;"); Environment.SetEnvironmentVariable("LIB", @"C:\Program Files\Microsoft Visual Studio 8\VC\ATLMFC\LIB;C:\Program Files\Microsoft Visual Studio 8\VC\LIB;C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\lib;C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\lib"); Environment.SetEnvironmentVariable("LIBPATH", @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;C:\Program Files\Microsoft Visual Studio 8\VC\ATLMFC\LIB"); Environment.SetEnvironmentVariable("Path", @"%Path%;C:\Program Files\Microsoft Visual Studio 8\Common7\IDE;C:\Program Files\Microsoft Visual Studio 8\VC\BIN"); // Compile program ProcessStartInfo psi = new ProcessStartInfo("cl.exe", @" -Fec:\testCompile\hello.exe -EHsc c:\testCompile\hello.cpp"); psi.CreateNoWindow = true; psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; psi.UseShellExecute = false; Process p = new Process(); p.StartInfo = psi; p.Start(); p.WaitForExit(); compilerMessages.Text = p.StandardOutput.ReadToEnd(); ; //Execute program ProcessStartInfo psi2 = new ProcessStartInfo(@"c:\testCompile\hello.exe"); psi2.CreateNoWindow = true; psi2.RedirectStandardError = true; psi2.RedirectStandardOutput = true; psi2.UseShellExecute = false; Process p2 = new Process(); p2.StartInfo = psi2; p2.Start(); p2.WaitForExit(); programOutput.Text = p2.StandardOutput.ReadToEnd(); } ///////////// Again, thanks! Tom
-
Well, yes and no, but certainly thanks for setting me on the right path. With some experimentation I came up with a successful C# handler (based on your code, but with necessary environment variables set--and with directories hard coded for my computer) for a "compile and run" button as follows: //////////////////////////// protected void CompileAndRun_Click(object sender, EventArgs e) { // Set up environment Environment.SetEnvironmentVariable("INCLUDE", @"C:\Program Files\Microsoft Visual Studio 8\VC\ATLMFC\INCLUDE;C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE;C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\include;C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\include;"); Environment.SetEnvironmentVariable("LIB", @"C:\Program Files\Microsoft Visual Studio 8\VC\ATLMFC\LIB;C:\Program Files\Microsoft Visual Studio 8\VC\LIB;C:\Program Files\Microsoft Visual Studio 8\VC\PlatformSDK\lib;C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\lib"); Environment.SetEnvironmentVariable("LIBPATH", @"C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727;C:\Program Files\Microsoft Visual Studio 8\VC\ATLMFC\LIB"); Environment.SetEnvironmentVariable("Path", @"%Path%;C:\Program Files\Microsoft Visual Studio 8\Common7\IDE;C:\Program Files\Microsoft Visual Studio 8\VC\BIN"); // Compile program ProcessStartInfo psi = new ProcessStartInfo("cl.exe", @" -Fec:\testCompile\hello.exe -EHsc c:\testCompile\hello.cpp"); psi.CreateNoWindow = true; psi.RedirectStandardError = true; psi.RedirectStandardOutput = true; psi.UseShellExecute = false; Process p = new Process(); p.StartInfo = psi; p.Start(); p.WaitForExit(); compilerMessages.Text = p.StandardOutput.ReadToEnd(); ; //Execute program ProcessStartInfo psi2 = new ProcessStartInfo(@"c:\testCompile\hello.exe"); psi2.CreateNoWindow = true; psi2.RedirectStandardError = true; psi2.RedirectStandardOutput = true; psi2.UseShellExecute = false; Process p2 = new Process(); p2.StartInfo = psi2; p2.Start(); p2.WaitForExit(); programOutput.Text = p2.StandardOutput.ReadToEnd(); } ///////////// Again, thanks! Tom
Glad I could help!
Internet - the worlds biggest dictionary