.net - How to read from Process.StandardOutput without redirecting it? (F#) -


i've got little function saves me headaches dealing horrible system.diagnostics.process api:

let hiddenexec (command: string, arguments: string) =     let startinfo = new system.diagnostics.processstartinfo(command)     startinfo.arguments <- arguments     startinfo.useshellexecute <- false      startinfo.redirectstandarderror <- true     startinfo.redirectstandardoutput <- true      use proc = system.diagnostics.process.start(startinfo)     proc.waitforexit()     (proc.exitcode,proc.standardoutput.readtoend(),proc.standarderror.readtoend()) 

this works great, because tuple of 3 elements exitcode, stdout , stderr results.

now, suppose don't want "hide" execution. is, want write hypothetical, simpler, exec function. solution not redirect stdout/stderr , we're done:

let exec (command: string, arguments: string) =     let startinfo = new system.diagnostics.processstartinfo(command)     startinfo.arguments <- arguments     startinfo.useshellexecute <- false      let proc = system.diagnostics.process.start(startinfo)     proc.waitforexit()     proc.exitcode 

however, nice if refactor 2 functions converge them single one, , pass "hidden" bool flag it:

let newexec (command: string, arguments: string, hidden: bool) = 

this way, newexec(_,_,false) return stdout,stderr (not exitcode, before). problem if don't redirection dance (startinfo.redirectstandarderror <- true) cannot read output later via proc.standardoutput.readtoend() because error standardout has not been redirected or process hasn't started yet.

another option redirect outputs, , if hidden flag passed not true, call console.writeline(eachoutput), not elegant because write buffers in 1 go, without intercalating stderr between stdout lines in screen in proper order come. , long running processes, hide incremental output until process has finished.

so what's alternative here? need resort using damned events process class? :(

cheers

i follow "parameterize things" principle.

in case, means finding differences between hiddenexec , exec , parameterizing these differences functions.

here's end when that:

let execwith configurestartinfo returnfromproc (command: string, arguments: string) =     let startinfo = new system.diagnostics.processstartinfo(command)     startinfo.arguments <- arguments     startinfo.useshellexecute <- false      // parameterize bit     configurestartinfo startinfo      use proc = system.diagnostics.process.start(startinfo)     proc.waitforexit()      // parameterize bit     returnfromproc proc 

note passing in various returnfromproc functions, can change type of return value, want.

now can define hiddenexec specify redirect , 3-tuple return value did originally:

/// specialize execwith redirect output. /// return exit code , output , error. /// signature: string * string -> int * string * string let hiddenexec =      let configurestartinfo (startinfo: system.diagnostics.processstartinfo) =         startinfo.redirectstandarderror <- true         startinfo.redirectstandardoutput <- true      let returnfromproc (proc:system.diagnostics.process) =                (proc.exitcode,proc.standardoutput.readtoend(),proc.standarderror.readtoend())      // partial application -- command & arguments passed later     execwith configurestartinfo returnfromproc  

the signature shows have want: pass command & arguments tuple , 3-tuple in return:

val hiddenexec : string * string -> int * string * string 

note i'm using partial application here. have defined hiddenexec explicit parameters this:

let hiddenexec (command, arguments) =  // (command, arguments) passed here      let configurestartinfo ...     let returnfromproc ...      execwith configurestartinfo returnfromproc (command, arguments) // (command, arguments) passed here 

similarly can define exec not use redirect, this:

/// specialize execwith not redirect output. /// return exit code. /// signature: string * string -> int let exec =      let configurestartinfo _  =         ()  // ignore input      let returnfromproc (proc:system.diagnostics.process) =          proc.exitcode          execwith configurestartinfo returnfromproc      // alternative version using `ignore` , lambda     // execwith ignore (fun proc -> proc.exitcode)     

again, signature shows have simpler version wanted: pass command & arguments tuple , exitcode in return:

val exec : string * string -> int  

Comments

Popular posts from this blog

gridview - Yii2 DataPorivider $totalSum for a column -

java - Suppress Jboss version details from HTTP error response -

Sass watch command compiles .scss files before full sftp upload -