tags:

views:

293

answers:

3

I have a process, i can start, and hide working fine, but i want to read from the console program, when i runs, not after, i tried to run a timer, anbd read at the tick, but my program just crashes and when it not do, i get nothing at all.

   startInfo= new ProcessStartInfo("cmd.exe");
   startInfo.Arguments ="/C uus.exe "+ arg.ToString();
   startInfo.RedirectStandardError = true;
   startInfo.RedirectStandardOutput = true;
   startInfo.UseShellExecute = false;
   startInfo.CreateNoWindow = true;
   this.timer1.Enabled=true;
   this.listBox1.Items.Clear();
   p= Process.Start(startInfo);
                            Application.DoEvents(); 

        void Timer1Tick(object sender, EventArgs e)
 {
  string str="";
  str=p.StandardOutput.ReadLine();
  if(str != null)
  {
   this.Text=str.ToString();
   this.listBox1.Items.Add(str);
  }
  Application.DoEvents();
 }

So what do i do to solve this?


Update: I tried bender suggestion now My program don't crash anymore, but also don't recvie any data

   proc.StartInfo.UseShellExecute=false;
   proc.StartInfo.CreateNoWindow=true;
   proc.StartInfo.RedirectStandardOutput=true;
   proc.StartInfo.RedirectStandardError=true;
   proc.StartInfo.FileName="uus.exe";
   proc.StartInfo.Arguments=arg;
   proc.OutputDataReceived += new System.Diagnostics.DataReceivedEventHandler(SortOutputHandler);
   proc.Start();
   proc.BeginOutputReadLine();

 void SortOutputHandler(object o,System.Diagnostics.DataReceivedEventArgs e)
 {
  string str="";
  string str2="";
  str=e.Data.ToString();
  if(str!=null && str!="")
  {
   this.listBox1.Items.Add(str.ToString());
   this.Text=str.ToString();
  }
  str2=proc.StandardOutput.ReadLine();
  if(str2!=null && str2!="")
  {
   this.lsw1.Items.Add(str2.ToString());
  }
 }

hmm?


Update: I have changed the handler, because i have being tell, it can't do it, that it wil be cross thread operation, usualyy i wille have get an error if it was.

private delegate void TextAdderDelegate(string str);

void TextAdder(string str)
{
   if(this.lsw1.InvokeRequired==true)
   {
      Invoke(new TextAdderDelegate(TextAdder),new object[] {str});
   }
   else
   {
      this.lsw1.Items.Add(str);
   }
}

void SortOutputHandler(object o,System.Diagnostics.DataReceivedEventArgs e)
{
   string str="";

   if(e!=null)
   {
      if(e.Data!=null)
      {
         str=e.Data.ToString();
      }
   }
   TextAdder(str);
}
+1  A: 

The problem is that you're running on one thread and trying to write using another. When you created your background thread using the Timer's tick event, it can't have frontend user input.

Perhaps if you explained the big picture of what you're trying to accomplish, we can better help you.

In the meantime, you might want to create threadsafe writes. This article will help you to understand the problem and solution to writing to form controls on different threads.

Rap
The program is a process whichs take some arguments, and if no erro happends run and close is selft, what i'am trying to do is run the process, read how long the process is done with the task, while it does the task not after, and write it in my program.>>In the meantime, you might want to single-thread it by avoiding the Timer tick and reading in the same process.You mean i should try to read in the function where i call the process?
A: 

You may create the Process instance explicitly (e.g. new Process)and use the OutputDataReceived event, the method BeginOutputReadLine() and, when finished CancelOutputRead() for that.

The event OutputDataReceived will be repeatedly called asynchronously from a different thread as soon output data is available.

Armin
I tried you solution, as update in the question, now it don't crash, but also i don't get any data at all, also i could not figure out where to place CancelOutputRead().
A: 

I assume you get an 'thread cross exception', this may be caused because you're updating your form controls on an other thread then the UI thread.

Mez
no, no error message at al.