使用 VB.net 读取和写入命令提示符控制台 [英] Reading and writing to a command prompt console using VB.net
问题描述
我在别处问过类似的问题,但也许我问的方式不对,或者我不够清楚,所以我再问一次.
I have asked a similar question elsewhere but perhaps I did not ask it the right way or I was not clear enough so I am asking again.
这是我想要的地方:
- 打开 Windows 命令提示符
- 通过 dos 命令运行 DOS 应用程序
- 阅读显示在 dos 框中的返回文本,并将其显示在我的 windows 窗体中的文本框中.这需要定期(例如每秒)重复一次,并且不应关闭 dos 框.
我一直在绕圈子试图使用 Process 和 StartInfo 命令,但它们只运行应用程序并立即关闭进程.我需要保持 dos 框打开并继续阅读由 dos 应用程序添加到其中的任何新文本.我也遇到了这个线程,它似乎回答了我的问题,但它是在 C# 中,我无法转换它:
I have been going round in circles trying to use the Process and StartInfo commands, but they only run the application and close the process right away. I need to keep the dos box open and keep reading any new text that is added to it by the dos application. I also came across this thread that seems to answer my problem, but it is to in C# and I could not convert it:
我确实到了打开命令提示符并启动应用程序的部分,但我不知道如何读取它时不时返回到 dos 框控制台的数据.我想不断检查变化,以便我可以对它们采取行动,也许使用计时器控件.
I did get to the part where I open the command prompt and get the application started, but I don't know how to read the data that it returns to the dos box console every now and then. I want to constantly check for changes so that I can act on them, perhaps using a timer control.
请帮忙.
谢谢!
我运行了由 Stevedog 提供的代码并像这样使用它:
I ran the code that was kindly provided by Stevedog and used it like this:
Private WithEvents _commandExecutor As New CommandExecutor()
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
_commandExecutor.Execute("c:progra~2zbarinzbarcam.exe", "")
End Sub
Private Sub _commandExecutor_OutputRead(ByVal output As String) Handles _commandExecutor.OutputRead
txtResult.Text = output
End Sub
但我得到的只是空白的 dos 框.zbarcam 应用程序运行正常,因为我可以看到相机预览,我也可以看到它检测二维码,但是文本没有显示在 dos 框中,并且 _commandExecutor_OutputRead
子不会被触发,除非我关闭DOS框.
But all I am getting is blank dos box. The zbarcam application runs properly because I can see the camera preview and I can also see it detecting QR Codes, but the text is not showing in the dos box and _commandExecutor_OutputRead
sub is not being triggered unless I close the DOS box.
推荐答案
那个 C# 示例很糟糕,因为它没有显示如何实际读取标准输出流.创建一个这样的方法:
That C# example is bad because it doesn't show how to actually read the standard output stream. Create a method like this:
Public Function ExecuteCommand(ByVal filePath As String, ByVal arguments As String) As String
Dim p As Process
p = New Process()
p.StartInfo.FileName = filePath
p.StartInfo.UseShellExecute = False
p.StartInfo.RedirectStandardInput = True
p.StartInfo.RedirectStandardOutput = True
p.Start()
p.WaitForExit()
Return p.StandardOutput.ReadToEnd()
End Function
那么你可以这样称呼它:
Then you can call it like this:
Dim output As String = ExecuteCommand("mycommand.exe", "")
当然这是同步调用.如果您希望它异步调用命令行并在完成时引发一个事件,这也是可能的,但需要更多的编码.
Of course this makes a synchronous call. If you want it to call the command line asynchronously and just raise an event when it's complete, that is possible too, but would require a little more coding.
例如,如果您想异步执行此操作并且只是在固定时间间隔内定期检查更多输出,例如,这是一个简单示例:
If you want to do it asynchronously and just keep periodically checking for more output on a fixed interval, for instance, here's a simple example:
Public Class CommandExecutor
Implements IDisposable
Public Event OutputRead(ByVal output As String)
Private WithEvents _process As Process
Public Sub Execute(ByVal filePath As String, ByVal arguments As String)
If _process IsNot Nothing Then
Throw New Exception("Already watching process")
End If
_process = New Process()
_process.StartInfo.FileName = filePath
_process.StartInfo.UseShellExecute = False
_process.StartInfo.RedirectStandardInput = True
_process.StartInfo.RedirectStandardOutput = True
_process.Start()
_process.BeginOutputReadLine()
End Sub
Private Sub _process_OutputDataReceived(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs) Handles _process.OutputDataReceived
If _process.HasExited Then
_process.Dispose()
_process = Nothing
End If
RaiseEvent OutputRead(e.Data)
End Sub
Private disposedValue As Boolean = False
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
If _process IsNot Nothing Then
_process.Kill()
_process.Dispose()
_process = Nothing
End If
End If
End If
Me.disposedValue = True
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
End Class
然后你可以这样使用它:
Then you could use it like this:
Public Class Form1
Private WithEvents _commandExecutor As New CommandExecutor()
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
_commandExecutor.Execute("D:SandboxSandboxSolutionConsoleCsinDebugConsoleCs.exe", "")
End Sub
Private Sub _commandExecutor_OutputRead(ByVal output As String) Handles _commandExecutor.OutputRead
Me.Invoke(New processCommandOutputDelegate(AddressOf processCommandOutput), output)
End Sub
Private Delegate Sub processCommandOutputDelegate(ByVal output As String)
Private Sub processCommandOutput(ByVal output As String)
TextBox1.Text = output
End Sub
Private Sub Form1_FormClosed(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
_commandExecutor.Dispose()
End Sub
End Class
这篇关于使用 VB.net 读取和写入命令提示符控制台的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!