Vb.net 如何在Visual Basic中逐行获取命令提示窗口的输出?
我试图逐行获取命令行输出,直到输出结束,但我无法这样做。我在表单中使用它,这个代码在单击按钮时执行Vb.net 如何在Visual Basic中逐行获取命令提示窗口的输出?,vb.net,cmd,Vb.net,Cmd,我试图逐行获取命令行输出,直到输出结束,但我无法这样做。我在表单中使用它,这个代码在单击按钮时执行 你能告诉我我的密码有什么问题吗 Dim proc As ProcessStartInfo = New ProcessStartInfo("cmd.exe") Dim pr As Process proc.CreateNoWindow = True proc.UseShellExecute = False proc.RedirectStandardInput = Tr
你能告诉我我的密码有什么问题吗
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()
执行此代码时,程序停止响应。我做了一些研究。adb帮助将输出写入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。不要对输出进行交互,也不要读取它!通常情况下,您不知道输出的长度(错误输出也是如此),因此需要为未知长度做好准备。由于您告诉Process类,您希望自己处理标准输出和标准错误,因此在这种情况下,您还需要:
- 输出数据接收
- 收到错误数据
列表(字符串)
,并在流程完成时输出特定行(=所有输出行都存在)
可能的解决方案如下所示:
' 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
14.10.2014 12:49:10
. Processing done.
-e - directs command to the only running emulator.
现在,即使adb写入错误输出,您也可以看到它。它也将完成
本例中的输出如下所示:
' 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
14.10.2014 12:49:10
. Processing done.
-e - directs command to the only running emulator.
另一种可能是将所有内容放在一个字符串中,在该过程完成后,在行尾(CRLF\r\n)拆分单个字符串,您将获得要筛选的行。还有
重定向标准错误
。Hi@Dmitry Kurilo我尝试了您建议的此方法。谢谢兄弟。但问题是我想把每一行输出放到一个单独的字符串中。稍后,我将合并需要的行,并删除不需要的行。这不仅仅是为了亚洲开发银行的帮助。我还想使用其他一些adb命令。你明白我想做什么吗?谢谢。嗨,德米特里·库里洛。非常感谢兄弟。我解决了我的问题。再看一遍你的代码后,我意识到我忘记了这一行。“pr.StandardInput.Close()”。我没有把它写进我的密码里。现在一切正常。谢谢兄弟。上帝保佑你。在我向Patsy道歉让他在我的代码上撞了头之后,我会给你绿色的记号。如果(不是进程。已退出)检查,否则你可能会丢失程序输出的最后一行。@MarkHurd谢谢你的提示。我已删除该行。@pasty我不仅仅使用adb help命令。我还使用了adb的一些其他命令。我知道输出的长度可能不同。我只给出了一个数组字符串20,假设输出行的数量是20。但问题是我想得到每个输出行并将其保存在单独的字符串中。然后,稍后我想只利用所需的轮廓,而不是不需要的轮廓,只利用所需的字符串。如何将out的每一行保存到一个单独的字符串中?我已经更新了我的答案-现在当流程完成时,只输出第4行。您可以根据需要更改代码。嗨@Pasty。我又看了一遍Dmitry Kurilo的答案,我意识到我没有把“pr.StandardInput.Close()”这一行放进去。现在我已经做到了,而且效果很好。很抱歉让你经历了所有的麻烦。我想给你们两个打绿色记号,但我不知道这是否可行。谢谢你,伙计