我试图逐行获取命令行输出,直到输出结束,但我无法这样做。我在我的表单中使用它,此代码在单击按钮时执行。
你能告诉我我的代码有什么问题吗?
Dim proc As ProcessStartInfo = New ProcessStartInfo("cmd.exe")
Dim pr As Process
proc.CreateNoWindow = True
proc.UseShellExecute = False
proc.RedirectStandardInput = True
proc.RedirectStandardOutput = True
pr = Process.Start(proc)
pr.StandardInput.WriteLine("cd C:\sdk\platform-tools\")
pr.StandardInput.WriteLine("adb help")
Dim helpArray(20) as String
For i as Integer 1 To 7
helpArray(i) = pr.StandardOutput.ReadLine()
Next
pr.StandardOutput.Close()
执行此代码时程序停止响应。
答案 0 :(得分:2)
我做过一些研究。 adb help将输出写入STDERR。所以你需要这样的东西:
Dim proc As ProcessStartInfo = New ProcessStartInfo("cmd.exe")
Dim pr As Process
proc.CreateNoWindow = True
proc.UseShellExecute = False
proc.RedirectStandardInput = True
proc.RedirectStandardOutput = True
pr = Process.Start(proc)
pr.StandardInput.WriteLine("C:\sdk\platform-tools")
pr.StandardInput.WriteLine("adb help 2>&1")
pr.StandardInput.Close()
Console.WriteLine(pr.StandardOutput.ReadToEnd())
pr.StandardOutput.Close()
抓住它。
例如,如果你调用ipconfig,则不需要2>& 1。
答案 1 :(得分:1)
不要对输出进行交互而不要阅读它!通常你不知道输出多长时间(同样也是错误输出),所以你需要准备一个未知的长度。既然您要告诉Process类,您想要自己处理标准输出和标准错误,那么您还需要bind to the events,在这种情况下:
或阻止当前进程并立即阅读完整输出,就像@Dmitry Kurilo在答案中所做的那样。我发现第一种方法更好,因为我不需要等待进程结束才能看到它的输出。 ProcessStartInfo.RedirectstandardError property的MSDN文档通过大量示例很好地解释了不同的可能性。
如果你想采取特定的路线,有很多可能性。一种方法是将每个输出(行)存储在委托中,稍后使用List(Of String)
使用它,并在完成该过程时输出特定行(=所有输出行都存在)。
可能的解决方案可能如下所示:
' store error output lines
dim lines = new List(of String)
dim executable = "c:\temp\android\sdk\platform-tools\adb.exe"
dim arguments = " help"
dim process = new Process()
process.StartInfo = createStartInfo(executable, arguments)
process.EnableRaisingEvents = true
addhandler process.Exited, Sub (ByVal sender As Object, ByVal e As System.EventArgs)
Console.WriteLine(process.ExitTime)
Console.WriteLine(". Processing done.")
' output line n when output is ready (= all lines are present)
Console.WriteLine(lines(4))
end sub
' catch standard output
addhandler process.OutputDataReceived, Sub (ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs)
if (not String.IsNullOrEmpty(e.Data))
Console.WriteLine(String.Format("{0}> {1}", DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss") ,e.Data))
end if
end sub
' catch errors
addhandler process.ErrorDataReceived, Sub (ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs)
'Console.WriteLine(String.Format("! {0}", e.Data))
' add every output line to the list of strings
lines.Add(e.Data)
end sub
' start process
dim result = process.Start()
' and wait for output
process.BeginOutputReadLine()
' and wait for errors :-)
process.BeginErrorReadLine()
private function createStartInfo(byval executable as String, byval arguments as String) as ProcessStartInfo
dim processStartInfo = new ProcessStartInfo(executable, arguments)
processStartInfo.WorkingDirectory = Path.GetDirectoryName(executable)
' we want to read standard output
processStartInfo.RedirectStandardOutput = true
' we want to read the standard error
processStartInfo.RedirectStandardError = true
processStartInfo.UseShellExecute = false
processStartInfo.ErrorDialog = false
processStartInfo.CreateNoWindow = true
return processStartInfo
end function
现在即使 adb 写入错误输出,您也可以看到它。它也将完整。
这种情况下的输出如下所示:
14.10.2014 12:49:10
. Processing done.
-e - directs command to the only running emulator.
另一种可能性是将所有内容放入一个字符串中,并且在该过程完成后将单个字符串拆分为行结尾(CRLF \ r \ n),您将获得要过滤的行。