vb.net - 将输出重定向到表单文本框

时间:2013-03-18 20:02:17

标签: vb.net process

我试图在我的vb.net项目中读取/使用python程序的输出到目前为止我没有得到任何结果。我想看到的是python程序运行(只是首先),并且所有输出都被重定向到文本框中。

我已经看了一些关于这个的其他帖子,但我要么缺少某些东西或者没有理解某些东西,因为我得到的只是空白输出。 公共类Form1

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    Dim PythonPath = "C:\Python27\"
    Dim strPath As String = Application.StartupPath
    MessageBox.Show(PythonPath & "python.exe  """ & strPath & "\Resources\import_logs.py"" ")

    Dim start_info As New ProcessStartInfo(TextBox1.Text)

    ' Make the process and set its start information.
    Dim process As New Process()
    process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
    process.StartInfo.FileName = PythonPath & "\python.exe"
    process.StartInfo.Arguments = """" & strPath & "\resources\import_logs.py"""""
    process.StartInfo.UseShellExecute = False
    process.StartInfo.CreateNoWindow = True
    process.StartInfo.RedirectStandardOutput = True
    'process.StartInfo.RedirectStandardError = True

    AddHandler process.OutputDataReceived, AddressOf proccess_OutputDataReceived

    process.Start()
    process.BeginOutputReadLine()
End Sub

Public Sub proccess_OutputDataReceived(ByVal sender As Object, ByVal e As DataReceivedEventArgs)
    On Error Resume Next
    ' output will be in string e.Data
    ' modify TextBox.Text here
    'Server_Logs.Text = e.Data  ` Does not display anything in textbox
    MsgBox(e.Data) 'It works but I want output in text box field
End Sub
End Class

最终我要将参数传递给python脚本,我想获得我可以使用的反馈(将错误插入数据库,完成时发送电子邮件等),所以我希望它能够在运行时捕获进程,而不仅仅是最后的数据转储。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

首先要做的事情 - 难怪你不确定你的代码有什么问题,你正在消除所有可能帮助你诊断错误的错误。这是VB.NET中On Error Resume Next的唯一目的。该非结构化错误处理仅包含 ,以便与VB的.NET版本向后兼容,现在是时候忘记它曾经存在过。您肯定不想在代码中使用它。 (我会说“在代码中你正在调试”,但所有代码都是调试的潜在候选者,忽略错误只是愚蠢。)

无论如何,关于具体问题。我们知道对MsgBox的调用有效,但是当您开始与表单上的控件进行交互时,它无法正常工作。所以有些东西在那里分崩离析。

事实证明,OutputDataReceived事件是在完全不同的线程上引发的,与用于创建进程的线程不同,而不是运行应用程序UI的线程。它实际上只是从系统线程池中检索一个线程。

这就是问题所在:你不能在创建这些对象的线程之外的线程上操作UI对象(至少不会跳过一些箍),这正是你的代码试图在这里做的。事实上,你可能会吞下一个例外,这个例外会让你知道这种情况。

简单的解决方法是将Process类的SynchronizingObject属性设置为一个UI组件(如表单或要输出的特定控件)。这会强制所有事件处理程序在创建该组件的同一线程上执行。此时,您的代码应该可以正常工作,因为您不会尝试进行任何跨线程的UI访问。 (消息框不容易受此影响,因为任何线程都可以显示消息框。您不是要尝试访问绑定到另一个线程的现有UI对象。)

或者,您可以通过使用委托和BeginInvoke方法在事件处理程序方法中自己处理编组,但这对我来说似乎是不必要的工作。