TextBox not updated in real time via BackgroundWorker with DataReceivedEventHandler enabled - c#

I need some help with BackgroundWorker. Using Visual Studio 2015 and its windows forms
I'm new to this kind of things and really have no idea how it works etc. The code i have so far is based on various posts on here.
worker_DoWork_ not being fired at all but no idea why. I believe this is something to do with DataRceivedEventHandler because when I move the If i move the worker.DoWork += worker_DoWork_; and worker.RunWorkerAsync(); into button clicked event and disable DataReceivedEventHandler, method worker_DoWork_ is fired and I can update textBox with any static text assigned under DoSomeWork.
Also, I have no idea how to pass outline data into the text box via DoSomeWork.
Can someone help out please.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace CMD_testing
{
public partial class Form1 : Form
{
BackgroundWorker worker;
private delegate void DELEGATE();
public Form1()
{
InitializeComponent();
worker = new BackgroundWorker();
}
private void button2_Click(object sender, EventArgs e)
{
Process process;
process = new Process();
process.StartInfo.FileName = #"C:\\Project\Test\Data.bat";
process.StartInfo.UseShellExecute = false;
// process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
process.StartInfo.RedirectStandardInput = true;
process.Start();
process.BeginOutputReadLine();
// process.WaitForExit();
// process.Close();
}
private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (outLine.Data != null)
{
Console.WriteLine("Im here...");
worker.DoWork += worker_DoWork_;
//worker.RunWorkerAsync();
Console.WriteLine("Im here NOW");
Console.WriteLine(outLine.Data); //its outputed fine into the console
}
}
private void worker_DoWork_(object sender, DoWorkEventArgs e)
{
Console.WriteLine("I'm at worker_DoWork_");
Delegate del = new DELEGATE(DoSomeWork);
this.Invoke(del);
}
private void DoSomeWork()
{
Thread.Sleep(1000);
textBox1.Text = "????"; // how to pass outline.Data in here
}
}
}

The problem is that you outline RunWorkerAsync();. This methods fires the DoWork-Event which handle your asynchronous code. Via the EventArgs of DoWork you can reuse your results back to your mainthread and print it to your textbox. You can get the result in the RunWorkerCompleted-Event. Here a small example based on your code:
public partial class Form1 : Form
{
BackgroundWorker worker;
public Form1()
{
InitializeComponent();
worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_Completed;
}
private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (outLine.Data != null)
{
if (!worker.IsBusy) //Check if Worker is working and avoid exception
worker.RunWorkerAsync();
}
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
//Process some Long-Running Task
Thread.Sleep(5000)
e.Result = "Done!";
}
private void worker_Completed(object sender, RunWorkerCompletedEventArgs e)
{
textbox.Text = e.Result.ToString();
}
}
}
Further you are maybe interested in Task Library which make the handling of threads easier.
UPDATE:
You say:
I want to update my Textbox in realtime.
This will print the text which your batchfile sends to Standardoutput directly in your textbox. So I don't think you need anymore.
private void OutputHandler(object sendingProcess, DataReceivedEventArgs e)
{
if (!string.IsNullOrWhiteSpace(e.Data))
BeginInvoke(new MethodInvoker(() => { textBox1.Text = e.Data; }));
}

Thanks to #Sebi I have managed to get all issues sorted. It turns out I do not need a BackgroundWorker as some people suggested.
See the final code which works like a charm:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
namespace CMD_testing
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
Process process;
process = new Process();
process.StartInfo.FileName = #"C:\\Project\Test\Other Data.bat";
process.StartInfo.UseShellExecute = false;
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardOutput = true;
process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);
process.StartInfo.RedirectStandardInput = true;
process.Start();
process.BeginOutputReadLine();
process.Close();
}
private void OutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
{
if (outLine.Data != null)
{
BeginInvoke(new MethodInvoker(() => { textBox1.AppendText(outLine.Data + Environment.NewLine); }));
}
}
}
}

Related

Not creating new Backgroundworker instance - C#

I am creating a progress form that utilizes a backgroundworker to run the process. It runs okay the first time the form is displayed, but after that I get the error
Additional information: This operation has already had OperationCompleted
called on it and further calls are illegal.
when I try to call the TheBackgroundworker.ReportProgress() method.
I am confused, because I am creating the progress form in a using block like this:
using (ProgressForm FPProgForm = new ProgressForm(TheUI))
{
FPProgForm.ShowDialog();
if (FPProgForm.DialogResult == DialogResult.OK)
{
// display results screen
}
}
And in the FPProgForm constructor, I am creating a new BackgroundWorker()
TheBackgroundworker = new BackgroundWorker();
So the BackGroundWorker should be brand new every time I create a new dialog.
Update: On request, here is the entire progress form class:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace FPDWF
{
public partial class ProgressForm : Form
{
public delegate void RunFunctionDelegate();
RunFunctionDelegate FuncToRun { get; } // function to be run
FPDesktopWFUI TheUI { get; }
BackgroundWorker TheBackgroundworker; // for internal use only, like a viagra demo
public ProgressForm(RunFunctionDelegate funcToRun, FPDesktopWFUI theUI)
{
InitializeComponent();
FuncToRun = funcToRun;
TheUI = theUI;
TheBackgroundworker = new BackgroundWorker();
InitializeBackgroundWorker();
// subscription to event stuff here: http://stackoverflow.com/questions/14871238/report-progress-backgroundworker-from-different-class-c-sharp
TheUI.OnProgressUpdate += FPProgUpdate;
}
// Set up the BackgroundWorker object by
// attaching event handlers.
private void InitializeBackgroundWorker()
{
// background worker stuff here: https://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
TheBackgroundworker.DoWork +=
new DoWorkEventHandler(TheBackgroundworker_DoWork);
TheBackgroundworker.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(TheBackgroundworker_RunWorkerCompleted);
TheBackgroundworker.ProgressChanged +=
new ProgressChangedEventHandler(TheBackgroundworker_ProgressChanged);
TheBackgroundworker.WorkerReportsProgress = true;
TheBackgroundworker.WorkerSupportsCancellation = true;
}
private void ProgressForm_Load(object sender, EventArgs e)
{
// progress bar stuff here: http://stackoverflow.com/questions/12126889/how-to-use-winforms-progress-bar
ui_progbar.Maximum = 100;
ui_progbar.Step = 1;
ui_progbar.Value = 0;
TheBackgroundworker.RunWorkerAsync();
}
private void ui_cancelbutton_Click(object sender, EventArgs e)
{
if (TheBackgroundworker.WorkerSupportsCancellation == true)
{
// Cancel the asynchronous operation.
TheBackgroundworker.CancelAsync(); // there really is no purpose to this as i can just set the contRunning flag I think
TheUI.contRunning = false; // i think this thread safe due to 'volatile flag', https://msdn.microsoft.com/en-us/library/7a2f3ay4(v=vs.100).aspx
resultLabel.Text = "Cancelling...";
}
}
// This event handler is where the time-consuming work is done.
private void TheBackgroundworker_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
FuncToRun();
}
// This event handler updates the progress.
private void TheBackgroundworker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// something to do here?
}
// This event handler deals with the results of the background operation.
private void TheBackgroundworker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (TheBackgroundworker.CancellationPending == true) // if (e.Cancelled == true)
{
this.DialogResult = DialogResult.Cancel;
this.Close();
}
else if (e.Error != null)
{
this.DialogResult = DialogResult.Abort;
resultLabel.Text = "Error: " + e.Error.Message;
ui_viewres_btn.Text = "Close";
ui_viewres_btn.Enabled = true;
}
else
{
this.DialogResult = DialogResult.OK;
ui_viewres_btn.Enabled = true;
}
}
private void FPProgUpdate(string progText, double prog)
{
// utilizing this: http://stackoverflow.com/a/14871753/3661120
int intProg = Convert.ToInt32(prog * 100);
if (!TheBackgroundworker.CancellationPending)
{
TheBackgroundworker.ReportProgress(intProg); // doesn't really do anything at this point, but whatev
base.Invoke((Action)delegate
{
resultLabel.Text = progText;
ui_progbar.Value = intProg;
});
}
}
private void ui_viewres_btn_Click(object sender, EventArgs e)
{
this.Close(); // closes the window
}
}
}
Update 2: even when I remove the offending TheBackgroundworker.ReportProgress(intProg); line, I am still getting this error:
Additional information: Invoke or BeginInvoke cannot be called on a
control until the window handle has been created.
You retrieve this error because you are subscribing to this event:
TheUI.OnProgressUpdate += FPProgUpdate;
Therefore FPProgUpdate calls ReportProgress() multiple times.
As you have already noticed, the following like is not necessary and you can remove it:
TheBackgroundworker.ReportProgress(intProg);
Thanks to Marc for the help on this. The solution was that I needed to unsubscribe FPProgUpdate from the TheUI.OnProgressUpdate event in the disposal method, which I had to override:
protected override void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
if (components != null)
{
components.Dispose();
}
// Dispose stuff here
TheUI.OnProgressUpdate -= FPProgUpdate;
}
disposed = true;
base.Dispose(disposing);
}
The disposal does not automatically unsubscribe, it seems like.
TheBackgroundworker.ReportProgress should only be called from inside of the thread that is executing DoWork. From your code it looks like FPProgUpdate contains a ReportProgress and is being called from some thread other than the thread that started DoWork.

C# Ping -t stopping by button

I have little problem with stopping infinite Pinging.
If you see in picture I ping IP 127.0.0.1 it has infinite ping ( -t ).
And I want do that when I Click Stop! button then it stops pinging.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using System.Diagnostics;
using System.Net;
using System.Management;
namespace PingProgramm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Thread th;
private void button1_Click(object sender, EventArgs e)
{
th = new Thread(thread1);
th.Start();
}
public void thread1()
{
try
{
string command = "/c ping -t " + textBox1.Text;
ProcessStartInfo procStartInfo = new ProcessStartInfo("CMD", command);
Process proc = new Process();
proc.StartInfo = procStartInfo;
procStartInfo.RedirectStandardOutput = true;
procStartInfo.RedirectStandardInput = true;
procStartInfo.RedirectStandardError = true;
procStartInfo.UseShellExecute = false;
procStartInfo.CreateNoWindow = true;
proc.OutputDataReceived += new DataReceivedEventHandler(proc_OutputDataReceived);
proc.Start();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
catch (Exception)
{
//if an error occurs with in the try block, it will handled here.
}
}
void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
string newLine = e.Data.Trim() + Environment.NewLine;
MethodInvoker append = () => richTextBox1.Text += newLine;
richTextBox1.BeginInvoke(append);
}
}
bool firstTime = true;
private void textBox1_Click(object sender, EventArgs e)
{
if (firstTime)
{
firstTime = false;
textBox1.Clear();
}
}
private void button2_Click(object sender, EventArgs e)
{
}
}
}
Best wishes
KLDesigns,
The simplest thing that might work in your current code is to get hold of your Process instance in the DataReceived event and cancel the process there (or send a Ctrl+C on the stdin).
void proc_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (stop)
{
// sender is our process instance
// so we can cast that safely here
var proc = (Process) sender;
// brutally kill it
proc.Kill();
// or more gently, send a ctrl+C
// http://stackoverflow.com/a/285041/578411
proc.StandardInput.Close();
}
if (e.Data != null)
{
string newLine = e.Data.Trim() + Environment.NewLine;
MethodInvoker append = () => richTextBox1.Text += newLine;
richTextBox1.BeginInvoke(append);
}
}
You can set the boolean stop in your click event handler:
bool stop = false;
private void button2_Click(object sender, EventArgs e)
{
stop = true;
}
Keep in mind that if you want to keep control over object instances you create consider keeping a reference to them. As you create the Process inside the thread your form can't reach it any more. If you would have made the proc an member of your form you could have called proc.StandardInput.Close() from your click event.

C# SelectVoice not changing in windows application but does in console

So I am trying to change a voice in C# for the System.Speech.Synthesis library. It will work for me when I attempt the code in console mode. However when I am working on a windows application it does not change the voice while giving no errors. Here is the code of the windows application that works asside from the voice change.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Speech.Synthesis;
using System.Speech.Recognition;
namespace JarvisRev1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.button1.Click += new EventHandler(button1_Click);
this.button2.Click += new EventHandler(button2_Click);
this.button3.Click += new EventHandler(button3_Click);
foreach (InstalledVoice voice in sSynth.GetInstalledVoices())
{
cbVoice.Items.Add(voice.VoiceInfo.Name);
}
}
SpeechSynthesizer sSynth = new SpeechSynthesizer();
PromptBuilder pBuilder = new PromptBuilder();
SpeechRecognitionEngine sRecognize = new SpeechRecognitionEngine();
private void button1_Click(object sender, EventArgs e)
{
pBuilder.ClearContent();
pBuilder.AppendText(textBox1.Text);
sSynth.SelectVoice("IVONA 2 Brian");
sSynth.SpeakAsync(pBuilder);
}
private void button2_Click(object sender, EventArgs e)
{
button2.Enabled = false;
button3.Enabled = true;
Choices sList = new Choices();
sList.Add(new string[] { "hello", "test", "it works", "how", "are", "you", "today", "i", "am", "fine", "exit", "close", "quit", "so", "hello how are you" });
Grammar gr = new Grammar(new GrammarBuilder(sList));
try
{
sRecognize.RequestRecognizerUpdate();
sRecognize.LoadGrammar(gr);
sRecognize.SpeechRecognized += sRecognize_SpeechRecognized;
sRecognize.SetInputToDefaultAudioDevice();
sRecognize.RecognizeAsync(RecognizeMode.Multiple);
sRecognize.Recognize();
}
catch
{
return;
}
}
private void button3_Click(object sender, EventArgs e)
{
sRecognize.RecognizeAsyncStop();
button2.Enabled = true;
button3.Enabled = false;
}
private void sRecognize_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
if (e.Result.Text == "exit")
{
Application.Exit();
}
else
{
textBox1.Text = textBox1.Text + " " + e.Result.Text.ToString();
}
}
}
}
This is the code in console mode that is working for me.
using System;
using System.Speech.Synthesis; // Add reference to System.Speech
class Program
{
static void Main(string[] args)
{
var synth = new SpeechSynthesizer();
synth.SelectVoice("IVONA 2 Brian");
synth.SpeakAsync("For you Sir, Always.");
foreach (var voice in synth.GetInstalledVoices())
{
Console.WriteLine(voice.VoiceInfo.Name);
}
Console.ReadLine();
}
}
Have same issue when Microsoft Irina Desktop voice is available in system. Workaround to set voice explicitly in prompt, e.g.:
using System.Speech.Synthesis;
var synth=new SpeechSynthesizer();
var builder=new PromptBuilder();
builder.StartVoice("Microsoft David Desktop");
builder.AppendText("Hello, World!");
builder.EndVoice();
synth.SpeakAsync(new Prompt(builder));
As you already utilize PromptBuilder, try to add StartVoice and EndVoice calls around text.

Windows Form - Running python script, redirected output delayed

I'm running a windows form with a background worker to update a textbox based on the output of a python script. Its all working pretty well, except the redirected output is not in real time; its delayed pretty significantly.
Any ideas how I can increase the redirected outputs response time?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.IO;
namespace JiraHeartBeat
{
public partial class Form1 : Form
{
delegate void AppendTextDelegate(string text);
BackgroundWorker Worker = new BackgroundWorker();
public Form1()
{
InitializeComponent();
Worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
Worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted);
}
void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
StartButton.PerformClick();
}
private void StartButton_Click(object sender, EventArgs e)
{
if (!Worker.IsBusy)
{
Worker.RunWorkerAsync();
}
}
public void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Process pro = new Process();
pro.StartInfo.RedirectStandardOutput = true;
pro.StartInfo.RedirectStandardError = true;
pro.StartInfo.UseShellExecute = false;
pro.StartInfo.CreateNoWindow = true;
pro.EnableRaisingEvents = true;
pro.OutputDataReceived += new DataReceivedEventHandler(OnDataReceived);
pro.ErrorDataReceived += new DataReceivedEventHandler(OnDataReceived);
pro.StartInfo.FileName = "C:\\Python27\\python.exe";
pro.StartInfo.Arguments = "\"C:\\Python27\\myscript.py\"";
try
{
pro.Start();
pro.BeginOutputReadLine();
pro.BeginErrorReadLine();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
Thread.Sleep(5000 * 60);
}
public void OnDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
string temp = (e.Data) + Environment.NewLine;
appendText(temp);
}
}
public void appendText(string text)
{
if (ResultTextBox.InvokeRequired)
{
ResultTextBox.Invoke(new AppendTextDelegate(appendText), new object[] { text });
}
else
{
ResultTextBox.AppendText(text);
}
}
}
}
Actually, the issue is that Python does not redirect output until the script is complete. I believe IronPython will redirect while the script is running (have not tested this though), but unfortunately, regular Python must wait for the script to end before redirecting output.
Try removing the below line from the Worker_DoWork, I suspect it is delaying the execution of the RunWorkerCompleted event.
Thread.Sleep(5000 * 60);
EDIT
Since the above approach was attempted and did not solve the problem entirely I investigated a bit further and confirmed that when capturing the output from a python script the response is delayed. However, by adding a call to sys.stdout.flush() I was able to get the desired behavior. Here is the python script I used which worked successfully in my test.
import time
import sys
for x in xrange(0,11):
print x
time.sleep(1)
sys.stdout.flush()

C# capturing python.exe output and displaying it in textbox

I have worked on this issue for a while. I can capture the output(live) of the console window just fine, but I can't capture the output of a python console application in real time. I can capture the output of the python program after it has finished running, but i don't want that.
I am using process from system.diagonistics. with a background worker.
I simply want to capture the python26 output onto a text box. I have tested my program with other custom applications, and it does display the output(live).
Help please
Thanks
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using System.IO;
namespace ProcessDisplayoutput
{
public partial class Form1 : Form
{
//Delegates
delegate void AppendTextDelegate(string text);
public Form1()
{
InitializeComponent();
Worker.DoWork += new DoWorkEventHandler(Worker_DoWork);
}
private void StartButton_Click(object sender, EventArgs e)
{
ResultTextBox.Clear();
if (!Worker.IsBusy)
{
Worker.RunWorkerAsync();
}
}
public void Worker_DoWork(object sender, DoWorkEventArgs e)
{
Process pro = new Process();
pro.StartInfo.RedirectStandardOutput = true;
pro.StartInfo.RedirectStandardError = true;
pro.StartInfo.UseShellExecute = false;
pro.StartInfo.CreateNoWindow = true;
pro.EnableRaisingEvents = true;
pro.OutputDataReceived +=new DataReceivedEventHandler(OnDataReceived);
pro.ErrorDataReceived +=new DataReceivedEventHandler(OnDataReceived);
//Test with random program worked,
//now need to test with python
//*****************TEST 1: PASSED **************************
pro.StartInfo.FileName = "C:\\TestProcessOutput.exe";
//*****************END TEST1*******************************
//*****************TEST 2: FAILED *************************
//pro.StartInfo.FileName = "C:\\Python26\\python.exe";
//pro.StartInfo.Arguments = "\"C:\\Python26\\testScript.py\"";
//*****************END TEST2 *******************************
StreamReader sr = null;
try
{
pro.Start();
pro.BeginOutputReadLine();
//An alternative option to display the output with the same results
//sr = pro.StandardOutput;
//string line = "";
//while ((line = sr.ReadLine()) != null)
//{
// appendText(line);
// }
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
public void OnDataReceived(object sender, DataReceivedEventArgs e)
{
if (e.Data != null)
{
string temp = (e.Data) + Environment.NewLine;
appendText(temp);
}
}
public void appendText(string text)
{
if (ResultTextBox.InvokeRequired)
{
ResultTextBox.Invoke(new AppendTextDelegate(appendText), new object[] { text });
}
else
{
ResultTextBox.AppendText(text);
}
}
I just ran into this question myself, and after a ton of experimenting, what worked for me was running the python process with the "-u" option, which makes the output unbuffered. With that, everything worked completely fine.
I ran into this problem while making a MiniConsole exactly for that purpose.
I used your technique with
pro.EnableRaisingEvents = true;
pro.OutputDataReceived +=new DataReceivedEventHandler(OnDataReceived);
pro.ErrorDataReceived +=new DataReceivedEventHandler(OnDataReceived);
The strange thing is that all the output was coming from ErrorDataReceived instead of OutputDataReceived (with valid commands).
So I think you're missing:
pro.BeginErrorReadLine();
Also I was starting the process in the main thread (I don't have any worker), using python27.
Here is the full start:
// executable: "c:\\python27\\python.exe", arguments: "myscript.py"
ProcessStartInfo startInfo = new ProcessStartInfo(executable, arguments);
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = false;
startInfo.RedirectStandardOutput = true;
startInfo.RedirectStandardError = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.WorkingDirectory = textBoxWorkingDirectory.Text;
try
{
Process p = new Process();
p.StartInfo = startInfo;
p.EnableRaisingEvents = true;
p.OutputDataReceived += new DataReceivedEventHandler(OnDataReceived);
p.ErrorDataReceived += new DataReceivedEventHandler(OnDataReceived);
p.Exited += new EventHandler(OnProcessExit);
p.Start();
p.BeginOutputReadLine();
p.BeginErrorReadLine();
}
I remember having a similar issue a while back and I think I did something similar to this in my .py scripts instead of using the print function:
sLog = 'Hello World!'
subprocess.Popen( 'echo ' + sLog, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True )
Not sure if I set the shell parameter to True or False though. Also not sure about all the "std" parameters. You might want to experiment a bit there.
If you're starting the Python process from your code, then THIS will make your life really easy and I think it's about the cleanest way to go.

Categories

Resources