2013-03-18 5 views
0

Я пытаюсь прочитать/использовать вывод из программы python в моем проекте vb.net, пока я не получаю никаких результатов. То, что я хотел бы увидеть, это запуск программы python (только сам по себе), и все выходные данные перенаправляются в текстовое поле.vb.net - перенаправить вывод в текстовое поле

Я просмотрел некоторые другие сообщения об этом, но я либо что-то пропустил, либо не понял что-то, так как все, что я получаю, - пустой результат. Public Class 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 

В конце концов я собираюсь передать аргументы сценария питона, и я хотел бы получить обратную связь, что я могу после этого использовать (ошибка вставки в базу данных, по электронной почте, когда это сделано, и т.д.) , поэтому я хотел бы, чтобы он захватил процесс во время работы, а не только дамп данных в конце.

Любая помощь будет высоко оценена.

ответ

1

Прежде всего, не удивительно, что вы не знаете, что не так с вашим кодом, вы заставляете замолчать все ошибки, которые могут помочь вам диагностировать его. Это единственная цель On Error Resume Next в VB.NET. Эта обработка неструктурированной ошибки включала только для обратной совместимости с версиями VB версии до версии .NET и пришло время забыть, что она когда-либо существовала. Вы обязательно не хотите использовать его в коде. (Я бы сказал, «в коде, что вы отлаживаете», но весь код является потенциальным кандидатом для отладки и игнорирования ошибок просто тупой.)

В любом случае, по конкретной проблеме. Мы знаем, что вызов MsgBox работает, но он не работает правильно, когда вы начинаете взаимодействовать с элементами управления в своей форме. Так что что-то там разваливается.

Оказалось, что событие OutputDataReceived создано в совершенно другом потоке, отличном от того, которое было создано для создания процесса и другого, чем при работе с пользовательским интерфейсом вашего приложения. Фактически он просто извлекает поток из пула системных потоков.

И вот в чем проблема: вы не можете манипулировать объектами пользовательского интерфейса в потоке, отличном от того, который создал эти объекты (по крайней мере, не перепрыгивая через некоторые обручи), что именно то, что ваш код пытается здесь сделать. На самом деле, вы, вероятно, проглатываете исключение, которое довольно утомительно информировало вас об этой ситуации.

Простым решением является установка свойства SynchronizingObject класса Process одному из компонентов вашего интерфейса (например, форме или определенному элементу управления, который вы хотите вывести). Это заставляет все обработчики событий выполняться в том же потоке, который создал этот компонент. В этот момент ваш код должен работать нормально, потому что вы не пытаетесь сделать какой-либо доступ к перекрестному интерфейсу. (Ящики сообщений не являются уязвимыми к этому, потому что любой нити может отобразить окно сообщения. Вы не пытаетесь получить доступ к существующему объекту пользовательского интерфейса, который связан с другим потоком.)

В качестве альтернативы, вы можете справиться с сортировочным самостоятельно в методе обработчика событий с использованием делегатов и метода BeginInvoke, но для меня это кажется ненужной работой.

Смежные вопросы