我正在尝试使应用程序运行多个(特别是 adb)命令并获取输出并显示在标签中。
首先,我需要启动进程来执行命令。感谢 stackoverflow 和 @pasty 我发现了这个(第二个回复):如何在 Visual Basic 中逐行获取命令提示符窗口的输出?
好吧,我认为因为它输出到控制台,所以将它写入标签很简单。大错!它给了我一个交叉线程错误!一点点谷歌搜索和堆栈溢出我发现了这个:vb.net 从一个线程访问,而不是在它创建的线程上
好吧,我试图实现它,但程序只是崩溃冻结。
这是代码:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
' store error output lines
Dim executable As String() = {"adb", "adb"}
Dim arguments As String() = {"help", "reboot"}
For i As Integer = 0 To 0
Dim process = New Process()
process.StartInfo = createStartInfo(executable(i), arguments(i))
process.EnableRaisingEvents = True
AddHandler process.Exited, Sub(ByVal sendera As Object, ByVal ea As System.EventArgs)
Console.WriteLine(process.ExitTime)
Console.WriteLine(". Processing done.")
'UpdateTextBox(ea)
End Sub
' catch standard output
AddHandler process.OutputDataReceived, Sub(ByVal senderb As Object, ByVal eb As DataReceivedEventArgs)
If (Not String.IsNullOrEmpty(eb.Data)) Then
Console.WriteLine(String.Format("{0}> {1}", DateTime.Now.ToString("dd.MM.yyyy HH:mm:ss"), eb.Data))
'UpdateTextBox(eb.Data)
End If
End Sub
' catch errors
AddHandler process.ErrorDataReceived, Sub(ByVal senderc As Object, ByVal ec As DataReceivedEventArgs)
Console.WriteLine(String.Format("! {0}", ec.Data))
Dim a As String = String.Format("! {0}", ec.Data)
'UpdateTextBox(a)
End Sub
' start process
Dim result = process.Start()
' and wait for output
process.BeginOutputReadLine()
' and wait for errors :-)
process.BeginErrorReadLine()
process.WaitForExit()
Next
End Sub
Private Sub UpdateTextBox(ByVal a As String)
If Me.InvokeRequired Then
Dim args() As String = {a}
Me.Invoke(New Action(Of String)(AddressOf UpdateTextBox), args)
Return
End If
Label1.Text += "a"
End Sub
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
和源代码:https : //github.com/iAmAOpenSource/SyncfusionWindowsFormsApplication3
调用process.WaitForExit()
将阻塞 UI 线程,直到产生的进程退出,但在处理输出时process.OutputDataReceived
您正在调用的事件Me.Invoke
试图在 UI 线程上运行代码,该线程被阻塞,因此程序冻结。您可以将逻辑Button1_Click
移到另一个线程上,例如
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Task.Run(
Sub()
... current logic
End Sub
)
End Sub
这样 UI 线程就不会被阻塞,Me.Invoke
调用也不会导致死锁。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句