c# - Capture command line output (by character output, not having to wait per line) -


i'm rendering output of command line process text box. problem in normal command prompt window, 1 of lines written has load bar kind of thing... every few seconds outputs "." screen.... after few dots, start new line , continue loading until has completed process.

with following code, instead of getting these "." appear 1 one, outputdatarecieved waiting whole line written out... load bar useless... ie, waits "............." , thennnn acts upon it.

is there way keep track of every character being output screen rather seems per line outputs?

//create process system.diagnostics.process process = new system.diagnostics.process();  // arguments.processstartinfo contains following declaration: // processstartinfo = new processstartinfo( "cmd.exe" ) // { //     workingdirectory = executabledirectoryname, //     useshellexecute = false, //     redirectstandardinput = true, //     redirectstandardoutput = true, //     createnowindow = true, // } process.startinfo = arguments.processstartinfo;  //start process stringbuilder sb = new stringbuilder();  bool alreadythrownexit = false;  // following event seems run per line output rather each character rendering command line process useless process.outputdatareceived += ( sender, e ) => {     sb.appendline( e.data );     commandlinehelper.commandlineoutput = sb.tostring();     arguments.delegateupdatetextmethod();      if( !alreadythrownexit )     {         if( process.hasexited )         {              alreadythrownexit = true;             arguments.delegatefinishmethod();             process.close();         }     } };  process.start(); process.standardinput.writeline( arguments.command ); process.standardinput.writeline( "exit" );  process.beginoutputreadline(); 

if want asynchronous processing of stdout of given process on per-character basis, can use textreader.readasync() method. instead of code have handle outputdatareceived event, this:

process.start();  // ignore task object, make compiler happy var _ = consumereader(process.standardoutput);  process.standardinput.writeline( arguments.command ); process.standardinput.writeline( "exit" ); 

where:

async task consumereader(textreader reader) {     char[] buffer = new char[1];      while ((await read.readasync(buffer, 0, 1)) > 0)     {         // process character...for example:         console.write(buffer[0]);     } } 

alternatively, create dedicated thread , use call textreader.read() in loop:

process.start();  new thread(() => {     int ch;      while ((ch = process.standardoutput.read()) >= 0)     {         // process character...for example:         console.write((char)ch);     } }).start();  process.standardinput.writeline( arguments.command ); process.standardinput.writeline( "exit" ); 

imho latter more efficient, doesn't require cross-thread synchronization. former more similar event-driven approach have had outputdatareceived event.


Comments