Thomas
Thomas

Reputation:

Read from console process

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);
}

Upvotes: 1

Views: 1150

Answers (3)

Mez
Mez

Reputation: 2857

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.

Upvotes: 0

Rap
Rap

Reputation: 7292

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.

Upvotes: 1

Armin
Armin

Reputation: 1062

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.

Upvotes: 0

Related Questions