redirecting standard output to a listbox

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • XxTIMOxX
    New Member
    • Jan 2014
    • 2

    redirecting standard output to a listbox

    I'm trying to run a cmd.exe from my form with some arguments and have it output the standard output live to a listbox. I have got it running to the point where the cmd file runs correctly, and if I change the code a bit I get "System.IO.Stre amReader" in my listbox, but not the actual output. This is my code:

    Code:
    private void startCmd(string cmdFileName, string argument)                  //startCmd test method 
            {                                                           
                var thread = new Thread(new ThreadStart(() =>
                {
                    Process p = new Process();                                                //create a new process for us to open our cmd line program
    
                    p.StartInfo.FileName = cmdFileName;                                       //use the given file name to seect the correct mining program
                    p.StartInfo.Arguments = argument;               //add all the arguments we appended together above into a string
                    p.StartInfo.UseShellExecute = false;                                      //don't use the shell to execute the cmd file                                           
                    p.StartInfo.RedirectStandardOutput = true;                                //redirect the standard output
                    p.StartInfo.RedirectStandardError = true;                                 //redirect standard errors
                    p.StartInfo.CreateNoWindow = true;                                        //don't create a new window
    
                    Process[] pname = Process.GetProcessesByName("minerd");                   //check all processes and put into array
                    if (pname.Length == 0)                                                    //test process name against length to see if it's running
                    {
                        p.Start();                                                            //if not running, start the program
                        StreamReader sr = p.StandardOutput;                                   //read the programs output into a streamreader
    
    
                        while (!p.HasExited)                                                  //while the program is still running
                        {
                            
                           // if (!sr.EndOfStream)                                               // TODO: This blocks the process for some reason...?
                            {
                                string procOutput = sr.ReadLine();
                                // trying to do the control update directly will result in an invalid cross-thread operation exception
                                // instead, we invoke the control update on the window thread using this.Invoke(...)
                                this.Invoke(new Action<string>(s => { lbCpuOutput.Items.Add(procOutput); }), procOutput);
                            }
                            //else Thread.Sleep(20);                                                 // no input, so just wait for 20ms and check again
                        }
                    }
                    else
                    {
                        MessageBox.Show("the program is already running");
                    }
    
                }));
    
                thread.Start();
    }
    Thank you for your help!
  • XxTIMOxX
    New Member
    • Jan 2014
    • 2

    #2
    I finally got it working, not need to reply.

    For anyone else who was having issues, I got this code from here which helped out a ton:

    Code:
    SynchronizationContext _syncContext;
    MyForm()
    {
        _syncContext = SynchronizationContext.Current;
    }
    
    void StartProcess()
    {
        var process = new Process
        {
            StartInfo = new ProcessStartInfo
            {
                FileName = "myProcess.exe",
                UseShellExecute = false,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
            }
        };
    
        process.OutputDataReceived += (sender, args) => Display(args.Data);
        process.ErrorDataReceived += (sender, args) => Display(args.Data);
    
        process.Start();
        process.BeginOutputReadLine();
        process.BeginErrorReadLine();
    
        process.WaitForExit(); //you need this in order to flush the output buffer
    }
    
    void Display(string output)
    {
        _syncContext.Post(_ => myTextBox.AppendText(output), null);
    }

    Comment

    Working...