[英]Visual Basic Capture output of cmd
我希望Visual Basic能夠在目錄“C:\\ projectTest \\”上運行“make”命令。
我試着用這個:
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
此代碼能夠捕獲控制台的“gcc ...”部分(來自Makefile),但不會捕獲錯誤(如果我手動打開cmd並在該目錄上運行make,則會彈出錯誤)。
如何捕獲出現的所有內容,包括錯誤?
不止一個問題。 首先,正如@ shf301已經告訴過你的那樣,你忘了閱讀stderr。 他反過來忘了添加額外的一行:
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()
還有一個非常麻煩的問題,你的事件處理程序運行得很晚。 他們在這個過程已經退出之后開火。 這些處理程序在線程池線程上運行的副作用。 在使用輸出變量之前,您需要等待任意(且不可饒恕)的時間量:
Do
Application.DoEvents()
Loop Until Process.HasExited
System.Threading.Thread.Sleep(1000)
這太難看了。 按照任何 IDE或編輯器的方式執行此操作。 將輸出重定向到臨時文件,然后讀取文件:
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
使用mystic命令行進行一些注釋:
那個2>&1
也會解決你原來的問題;)
錯誤通常寫入StandardError
流,您只讀取StandardOutput
流。 為ErrorDataReceived
事件添加事件處理程序,您應該看到錯誤。
AddHandler Process.ErrorDataReceived, _
Sub(processSender As Object, lineOut As DataReceivedEventArgs)
output += lineOut.Data + vbCrLf
End Sub
像我這樣的人想知道為什么我們不能在異步模式下得到錯誤。 添加行
process.BeginErrorReadLine()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.