Visual Basic Capture output of cmd

后端 未结 3 465
夕颜
夕颜 2020-12-04 02:28

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 = St         


        
相关标签:
3条回答
  • 2020-12-04 02:56

    for people like me that are wondering why we cant get errorstream, in async mode. add line

    process.BeginErrorReadLine()
    
    0 讨论(0)
  • 2020-12-04 02:59

    Errors are generally written to the StandardError stream and you are only reading the StandardOutput stream. Add an event handler for the ErrorDataReceived event and you should see the errors.

    AddHandler Process.ErrorDataReceived, _
           Sub(processSender As Object, lineOut As DataReceivedEventArgs)
               output += lineOut.Data + vbCrLf
           End Sub
    
    0 讨论(0)
  • 2020-12-04 03:01

    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:

    • /c tells cmd.exe to execute just the single command and then exit
    • 1> redirects the output to the temporary file
    • 2>&1 tells cmd.exe to redirect stderr to stdout
    • the triple double quotes ensures that spaces in the tempfile name don't cause trouble.

    That same 2>&1 would also have fixed your original problem ;)

    0 讨论(0)
提交回复
热议问题