我在其他地方也提过一个类似的问题,但也许我没有正确地问,或者我不清楚,所以我再次问。
这是我想要得到的地方:
我一直在试图使用Process和StartInfo命令,但是他们只运行应用程序并立即closures这个过程。 我需要保持dos框打开,并继续阅读由dos应用程序添加到它的任何新文本。 我也遇到这个线程似乎回答我的问题,但它是在C#中,我无法将其转换:
阅读Windows命令提示标准输出
我确实进入了打开命令提示符并启动应用程序的部分,但我不知道如何读取它现在返回到dos框控制台的数据。 我想不断检查变化,以便我可以采取行动,也许使用计时器控制。
请帮忙。
谢谢!
我运行了由Stevedog提供的代码,并像这样使用它:
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~2\zbar\bin\zbarcam.exe", "") End Sub Private Sub _commandExecutor_OutputRead(ByVal output As String) Handles _commandExecutor.OutputRead txtResult.Text = output End Sub
但是我所得到的是空白的dos框。 zbarcam应用程序运行正常,因为我可以看到相机预览,我也可以看到它检测到QR码,但是文本没有显示在dos框中,除非closuresDOS框,否则_commandExecutor_OutputRead
子程序不会被触发。
该C#示例是坏的,因为它不显示如何实际读取标准输出流。 创建一个像这样的方法:
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
那么你可以这样调用它:
Dim output As String = ExecuteCommand("mycommand.exe", "")
当然这是一个同步调用。 如果你想要它异步地调用命令行,并且在事件完成时引发一个事件,这也是可能的,但是需要更多的编码。
如果你想异步执行,只需定期在固定的时间间隔内检查更多的输出,例如,下面是一个简单的例子:
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
那么你可以像这样使用它:
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:\Sandbox\SandboxSolution\ConsoleCs\bin\Debug\ConsoleCs.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
这些转换器通常在事件时失败。
该代码的直接翻译将如下所示:
Dim proc as Process Sub RunApp proc = new Process() proc.StartInfo.FileName = "your_app.exe" proc.StartInfo.Arguments = "" proc.StartInfo.UseShellExecute = false proc.StartInfo.RedirectStandardInput = true proc.StartInfo.RedirectStandardOutput = true AddHandler proc.OutputDataReceived, AddressOf InterProcOutputHandler proc.Start() proc.WaitForExit() End Sub Sub InterProcOutputHandler(sendingProcess as object, outLine as DataReceivedEventArgs) 'Read data here 'Send command if necessary proc.StandardInput.WriteLine("your_command") End Sub
proc.OutputDataReceived
不是一个属性,而是一个事件 。
要订阅事件,在C#
使用event += handler
,而在VB.NET
使用AddHandler event, AddressOf handler
。