Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. HOWTO: start, get partial output and kill a console application from c#

HOWTO: start, get partial output and kill a console application from c#

Scheduled Pinned Locked Moved C#
csharphelp
10 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jancg
    wrote on last edited by
    #1

    All, I have a console application that's not mine; it cannot be modified. After starting it with a bunch of command line parameters, it computes something and displays the result on it's console. I would like to get the PARTIAL output and then kill it. I have found several code examples that seemed promising. My problem is that I can't seem to read any output before the program is finished and I need partial output to decide to kill it, since it will compute much more that I don't need after the initial computations. Jan C. de Graaf

    F L P 3 Replies Last reply
    0
    • J jancg

      All, I have a console application that's not mine; it cannot be modified. After starting it with a bunch of command line parameters, it computes something and displays the result on it's console. I would like to get the PARTIAL output and then kill it. I have found several code examples that seemed promising. My problem is that I can't seem to read any output before the program is finished and I need partial output to decide to kill it, since it will compute much more that I don't need after the initial computations. Jan C. de Graaf

      F Offline
      F Offline
      Fla_Golfr
      wrote on last edited by
      #2

      I am assumming you are talking about a console program that runs from a command window? If so the open a second command window. In the first command window,start the program and pipe output to a text file, and in the other command window do a type command on the text file with a more option pipe. As the file fills up you can scan it at your own reading pace.

      J 1 Reply Last reply
      0
      • F Fla_Golfr

        I am assumming you are talking about a console program that runs from a command window? If so the open a second command window. In the first command window,start the program and pipe output to a text file, and in the other command window do a type command on the text file with a more option pipe. As the file fills up you can scan it at your own reading pace.

        J Offline
        J Offline
        jancg
        wrote on last edited by
        #3

        Thank for your quick response! I can run the console program from a command window yes. >> with a more option pipe What is a "more option pipe" ? Is this like 'tail' in most unixes? Can you give an example please. I was hoping to use C# and the Process class and the RedirectStandardOutput option. But ran into the problem I described in my original question. Jan.

        1 Reply Last reply
        0
        • J jancg

          All, I have a console application that's not mine; it cannot be modified. After starting it with a bunch of command line parameters, it computes something and displays the result on it's console. I would like to get the PARTIAL output and then kill it. I have found several code examples that seemed promising. My problem is that I can't seem to read any output before the program is finished and I need partial output to decide to kill it, since it will compute much more that I don't need after the initial computations. Jan C. de Graaf

          L Offline
          L Offline
          Luc Pattyn
          wrote on last edited by
          #4

          when done correctly, one can get data from both the output and the error stream of a running app. using Stream.ReadToEnd() would not be part of the correct way; using an extra thread would. So maybe you should show a relevant snippet of your code for people to comment on. :)

          Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

          Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

          J 2 Replies Last reply
          0
          • L Luc Pattyn

            when done correctly, one can get data from both the output and the error stream of a running app. using Stream.ReadToEnd() would not be part of the correct way; using an extra thread would. So maybe you should show a relevant snippet of your code for people to comment on. :)

            Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

            Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

            J Offline
            J Offline
            jancg
            wrote on last edited by
            #5

            I will post some code this evening when I continue experimenting at home. I already tried using the available events on the Process class but those didn't fire untill the console application was finished. I will try a background thread this evening and see how far I get. Thanks.

            1 Reply Last reply
            0
            • L Luc Pattyn

              when done correctly, one can get data from both the output and the error stream of a running app. using Stream.ReadToEnd() would not be part of the correct way; using an extra thread would. So maybe you should show a relevant snippet of your code for people to comment on. :)

              Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

              Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

              J Offline
              J Offline
              jancg
              wrote on last edited by
              #6

              The code below will display "Started!" in the textbox immediately. Next it will hit the TimerCallBack method every second after the initial 5 seconds of computation. As it is supposed to. Saidly Peek() return -1 up to the moment the console program finishes:( I know for sure output has already been written! If I test the same from a command window, adding " > output.log" to the command line, the output goes into output.log but not untill the program finishes :( If I start the program normally from a command window, output is written to the console line-by-line!

              using System;
              using System.Diagnostics;
              using System.Windows.Forms;

              namespace WindowsFormsApplication1
              {
              public partial class Form1 : Form
              {

              public Form1()
              {
              InitializeComponent();
              }

              private Process process;

              private void Form1_Load(object sender, EventArgs e)
              {
              process = new Process();
              process.StartInfo.FileName = @"D:\Users\Jan C. de Graaf\Documents\Othello\test\zebra.exe";
              process.StartInfo.Arguments = "-b 0 -h 24 -l 28 30 30 28 30 30 -r 0 -slack 0.0 -learn 26 22 -private -log hqbook.txt -test";
              process.StartInfo.WorkingDirectory = @"D:\Users\Jan C. de Graaf\Documents\Othello\test";
              process.StartInfo.UseShellExecute = false;
              process.StartInfo.RedirectStandardOutput = true;
              process.Start();

              new System.Threading.Timer(new System.Threading.TimerCallback(TimerCallback), null, 5000, 1000);

              textBox1.Text = "Started!\r\n";
              }

              void TimerCallback(object state)
              {
              while (process.StandardOutput.Peek() > -1)
              {
              var data = process.StandardOutput.ReadLine();
              textBox1.Invoke((MethodInvoker)delegate{textBox1.Text += data + "\r\n";});
              }
              }
              }
              }

              L 1 Reply Last reply
              0
              • J jancg

                The code below will display "Started!" in the textbox immediately. Next it will hit the TimerCallBack method every second after the initial 5 seconds of computation. As it is supposed to. Saidly Peek() return -1 up to the moment the console program finishes:( I know for sure output has already been written! If I test the same from a command window, adding " > output.log" to the command line, the output goes into output.log but not untill the program finishes :( If I start the program normally from a command window, output is written to the console line-by-line!

                using System;
                using System.Diagnostics;
                using System.Windows.Forms;

                namespace WindowsFormsApplication1
                {
                public partial class Form1 : Form
                {

                public Form1()
                {
                InitializeComponent();
                }

                private Process process;

                private void Form1_Load(object sender, EventArgs e)
                {
                process = new Process();
                process.StartInfo.FileName = @"D:\Users\Jan C. de Graaf\Documents\Othello\test\zebra.exe";
                process.StartInfo.Arguments = "-b 0 -h 24 -l 28 30 30 28 30 30 -r 0 -slack 0.0 -learn 26 22 -private -log hqbook.txt -test";
                process.StartInfo.WorkingDirectory = @"D:\Users\Jan C. de Graaf\Documents\Othello\test";
                process.StartInfo.UseShellExecute = false;
                process.StartInfo.RedirectStandardOutput = true;
                process.Start();

                new System.Threading.Timer(new System.Threading.TimerCallback(TimerCallback), null, 5000, 1000);

                textBox1.Text = "Started!\r\n";
                }

                void TimerCallback(object state)
                {
                while (process.StandardOutput.Peek() > -1)
                {
                var data = process.StandardOutput.ReadLine();
                textBox1.Invoke((MethodInvoker)delegate{textBox1.Text += data + "\r\n";});
                }
                }
                }
                }

                L Offline
                L Offline
                Luc Pattyn
                wrote on last edited by
                #7

                So you're saying that attempt failed. There are maybe a dozen more ways to do things. I suggest you dedicate a thread (could be a BGW); that way you don't need a timer, don't need Peek at all, you just do a blocking ReadLine in a loop, until the main thread decides all is done. I did this, all the way back, using .NET 1.0 and Windows 98, and I can assure you there have been some bugs in .NET 1.x making it pretty hard; Since NT/XP the code got simpler and it now runs like a charm, one thread for stdout, one for stderr, and their output intertwines as it would in a DOS window (Command Prompt). Here is a typical receiver thread (the output() method is likely to contain a Control.Invoke):

                private void stdoutReader(object dummy) {
                	for (; threadsRunning && stdoutLines
                

                Mind you, there is some buffering going on, in the target app and in your app, so don't expect the output right away, there will be say some delays, but not seconds, and certainly not till the target app finishes. And the DOS prompt/command window (or something deep inside Windows) is smart enough to adapt the buffering depending on how things get used, so a pipe may well have a larger buffer than a direct interactive invocation.

                Due to the buffering and sometimes automatic but delayed flushing, determining the end of the output may be a little tricky too; here is one possibility (code executed in the main thread):

                proc.WaitForExit();
                // wait for threads to consume all output
                for (; ; ) {
                	if (stdoutDone&&stderrDone) break;
                	int cur=stdoutLines+stderrLines;
                	Thread.Sleep(500);
                	if (cur>=stdoutLines+stderrLines) break;
                }
                threadsRunning=false;
                

                :)

                Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

                Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

                modified on Wednesday, November 24, 2010 5:09 PM

                J 1 Reply Last reply
                0
                • J jancg

                  All, I have a console application that's not mine; it cannot be modified. After starting it with a bunch of command line parameters, it computes something and displays the result on it's console. I would like to get the PARTIAL output and then kill it. I have found several code examples that seemed promising. My problem is that I can't seem to read any output before the program is finished and I need partial output to decide to kill it, since it will compute much more that I don't need after the initial computations. Jan C. de Graaf

                  P Offline
                  P Offline
                  PIEBALDconsult
                  wrote on last edited by
                  #8

                  Try this[^].

                  1 Reply Last reply
                  0
                  • L Luc Pattyn

                    So you're saying that attempt failed. There are maybe a dozen more ways to do things. I suggest you dedicate a thread (could be a BGW); that way you don't need a timer, don't need Peek at all, you just do a blocking ReadLine in a loop, until the main thread decides all is done. I did this, all the way back, using .NET 1.0 and Windows 98, and I can assure you there have been some bugs in .NET 1.x making it pretty hard; Since NT/XP the code got simpler and it now runs like a charm, one thread for stdout, one for stderr, and their output intertwines as it would in a DOS window (Command Prompt). Here is a typical receiver thread (the output() method is likely to contain a Control.Invoke):

                    private void stdoutReader(object dummy) {
                    	for (; threadsRunning && stdoutLines
                    

                    Mind you, there is some buffering going on, in the target app and in your app, so don't expect the output right away, there will be say some delays, but not seconds, and certainly not till the target app finishes. And the DOS prompt/command window (or something deep inside Windows) is smart enough to adapt the buffering depending on how things get used, so a pipe may well have a larger buffer than a direct interactive invocation.

                    Due to the buffering and sometimes automatic but delayed flushing, determining the end of the output may be a little tricky too; here is one possibility (code executed in the main thread):

                    proc.WaitForExit();
                    // wait for threads to consume all output
                    for (; ; ) {
                    	if (stdoutDone&&stderrDone) break;
                    	int cur=stdoutLines+stderrLines;
                    	Thread.Sleep(500);
                    	if (cur>=stdoutLines+stderrLines) break;
                    }
                    threadsRunning=false;
                    

                    :)

                    Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

                    Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

                    modified on Wednesday, November 24, 2010 5:09 PM

                    J Offline
                    J Offline
                    jancg
                    wrote on last edited by
                    #9

                    Thanks for your tips. Still no luck. Code based on your clear tips below. I must admit that I didn't expect this to work since it is essentially the same as my previous attempt. In my previou spost I mentioned that while running the console program from a command window displayed output neatly; every now and then a line of text. When adding " > output.log" to the command line, all output winds up in output.log but NOT UNTILL the console program finishes! So here we have the same behaviour as in my c# program! Perhaps the cause is the fact that this is not a native windows console program; it need cygwin1.dll to work. Might this cause the strange behaviour?

                    using System;
                    using System.Diagnostics;
                    using System.Windows.Forms;
                    using System.Threading;

                    namespace WindowsFormsApplication1
                    {
                    public partial class Form1 : Form
                    {
                    public Form1()
                    {
                    InitializeComponent();
                    }

                    private Process process;

                    private void Form1_Load(object sender, EventArgs e)
                    {
                    process = new Process();
                    process.StartInfo.FileName = @"D:\Users\Jan C. de Graaf\Documents\Othello\test\zebra.exe";
                    process.StartInfo.Arguments = "-b 0 -h 24 -l 28 30 30 28 30 30 -r 0 -slack 0.0 -learn 26 22 -private -log hqbook.txt -test";
                    process.StartInfo.WorkingDirectory = @"D:\Users\Jan C. de Graaf\Documents\Othello\test";
                    process.StartInfo.UseShellExecute = false;
                    process.StartInfo.RedirectStandardOutput = true;
                    process.Start();

                    var thread = new Thread(new ThreadStart(GetOutputAndDisplay));
                    thread.Start();

                    textBox1.Text = "Started!\r\n";
                    }

                    void GetOutputAndDisplay()
                    {
                    string output;
                    do
                    {
                    output = process.StandardOutput.ReadLine();
                    textBox1.Invoke((MethodInvoker)delegate { textBox1.Text += output + "\r\n"; });
                    }
                    while (output != null);
                    }
                    }
                    }

                    L 1 Reply Last reply
                    0
                    • J jancg

                      Thanks for your tips. Still no luck. Code based on your clear tips below. I must admit that I didn't expect this to work since it is essentially the same as my previous attempt. In my previou spost I mentioned that while running the console program from a command window displayed output neatly; every now and then a line of text. When adding " > output.log" to the command line, all output winds up in output.log but NOT UNTILL the console program finishes! So here we have the same behaviour as in my c# program! Perhaps the cause is the fact that this is not a native windows console program; it need cygwin1.dll to work. Might this cause the strange behaviour?

                      using System;
                      using System.Diagnostics;
                      using System.Windows.Forms;
                      using System.Threading;

                      namespace WindowsFormsApplication1
                      {
                      public partial class Form1 : Form
                      {
                      public Form1()
                      {
                      InitializeComponent();
                      }

                      private Process process;

                      private void Form1_Load(object sender, EventArgs e)
                      {
                      process = new Process();
                      process.StartInfo.FileName = @"D:\Users\Jan C. de Graaf\Documents\Othello\test\zebra.exe";
                      process.StartInfo.Arguments = "-b 0 -h 24 -l 28 30 30 28 30 30 -r 0 -slack 0.0 -learn 26 22 -private -log hqbook.txt -test";
                      process.StartInfo.WorkingDirectory = @"D:\Users\Jan C. de Graaf\Documents\Othello\test";
                      process.StartInfo.UseShellExecute = false;
                      process.StartInfo.RedirectStandardOutput = true;
                      process.Start();

                      var thread = new Thread(new ThreadStart(GetOutputAndDisplay));
                      thread.Start();

                      textBox1.Text = "Started!\r\n";
                      }

                      void GetOutputAndDisplay()
                      {
                      string output;
                      do
                      {
                      output = process.StandardOutput.ReadLine();
                      textBox1.Invoke((MethodInvoker)delegate { textBox1.Text += output + "\r\n"; });
                      }
                      while (output != null);
                      }
                      }
                      }

                      L Offline
                      L Offline
                      Luc Pattyn
                      wrote on last edited by
                      #10

                      jancg wrote:

                      t need cygwin1.dll to work. Might this cause the strange behaviour?

                      Absolutely. It tells me your target app is essentially a kind of Unix/Linux thingy, and CYGWIN has to do god knows what to make it behave (a bit) under Windows. There still might be a solution, however I don't know it; I'm unfamiliar with the CYGWIN + .NET combination. If the app is related to www.zebra.com by chance, you might ask them; they just might have run into this before and hold a solution. :)

                      Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles] Nil Volentibus Arduum

                      Please use <PRE> tags for code snippets, they preserve indentation, and improve readability.

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups