I want Visual Basic to be able to run the "make" command on the directory "C:\projectTest\".
I tried to use this:
Dim output As String = String.Empty
Using Process As New Process
Process.StartInfo = New ProcessStartInfo("cmd")
Process.StartInfo.WorkingDirectory = "C:\projectTest\"
Process.StartInfo.UseShellExecute = False
Process.StartInfo.CreateNoWindow = True
Process.StartInfo.RedirectStandardInput = True
Process.StartInfo.RedirectStandardOutput = True
Process.StartInfo.RedirectStandardError = True
Process.Start()
Process.BeginOutputReadLine()
AddHandler Process.OutputDataReceived,
_
Sub(processSender As Object, lineOut As DataReceivedEventArgs)
output += lineOut.Data + vbCrLf
End Sub
Using InputStream As System.IO.StreamWriter = Process.StandardInput
InputStream.AutoFlush = False
InputStream.WriteLine("make")
End Using
Do
Application.DoEvents()
Loop Until Process.HasExited
End Using
This code is able to capture the "gcc ..." part of the console (comes from the Makefile), but will not capture the error (which does pop up if I manually open cmd and run make on that directory).
How can I capture everything that appears including the error?
More than one problem. First off, as @shf301 already told you, you forgot to read stderr. He in turn forgot to add an extra line:
Process.Start()
AddHandler Process.OutputDataReceived, _
Sub(processSender As Object, lineOut As DataReceivedEventArgs)
output += lineOut.Data + vbCrLf
End Sub
Process.BeginOutputReadLine()
AddHandler Process.ErrorDataReceived, _
Sub(processSender As Object, lineOut As DataReceivedEventArgs)
output += lineOut.Data + vbCrLf
End Sub
Process.BeginErrorReadLine()
There's another very cumbersome problem, your event handlers run late. They fire after the process has already exited. A side effect of these handlers running on a thread-pool thread. You'll need to wait for an arbitrary (and unguessable) amount of time before you use the output variable:
Do
Application.DoEvents()
Loop Until Process.HasExited
System.Threading.Thread.Sleep(1000)
This is too ugly. Do this the way that any IDE or editor does it. Redirect the output to a temporary file and read the file afterwards:
Dim tempfile As String = System.IO.Path.GetTempFileName
Using Process As New Process
Process.StartInfo = New ProcessStartInfo("cmd.exe")
Process.StartInfo.Arguments = "/c make 1> """ + tempfile + """ 2>&1"
Process.StartInfo.WorkingDirectory = "C:\projectTest"
Process.StartInfo.UseShellExecute = False
Process.StartInfo.CreateNoWindow = True
Process.Start()
Process.WaitForExit()
output = System.IO.File.ReadAllText(tempfile)
System.IO.File.Delete(tempfile)
End Using
Some annotation with the mystic command line:
That same 2>&1
would also have fixed your original problem ;)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With