use System.Diagnostics namespace Cobra.Core extend Process def runAndCaptureOutput as ProcessOutput """ Example: p = System.Diagnostics.Process() p.startInfo.fileName = 'some-program' p.startInfo.arguments = 'foo bar baz' output = p.runAndCaptureAllOutput trace p, p.exitCode, output """ return .runAndCaptureOutput(false) def runAndCaptureOutput(verbose as bool) as ProcessOutput # Reference: http://msdn2.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline(VS.80).aspx if verbose print 'command : "[.startInfo.fileName]"' print 'arguments : "[.startInfo.arguments]"' output = ProcessOutput(this) try .start .beginOutputReadLine .beginErrorReadLine .waitForExit finally output.cleanUp if verbose # could put this in the output-receiving methods on ProcessOutput bar = '----------------------------------------' print 'output:' print bar print output.combinedOutput print bar return output def runAndCaptureAllOutput as String """ deprecated. Use .runAndCaptureOutput """ return .runAndCaptureAllOutput(false) def runAndCaptureAllOutput(verbose as bool) as String return .runAndCaptureOutput(verbose).combinedOutput class ProcessOutput """ The return value for Process.runAndCaptureOutput. Provides .standardOutput, .errorOutput and .combineOutput. """ var _process as Process? var _standardOutput = StringBuilder() var _errorOutput = StringBuilder() var _combinedOutput = StringBuilder() cue init(p as Process) base.init _process = p info = p.startInfo info.redirectStandardOutput = true info.redirectStandardError = true info.useShellExecute = false # otherwise: System.InvalidOperationException: UseShellExecute must be false when redirecting I/O. info.createNoWindow = true # otherwise: Console window is briefly displayed when run from a winexe program listen _process.outputDataReceived, DataReceivedEventHandler(ref _outputLineReceived) listen _process.errorDataReceived, DataReceivedEventHandler(ref _errorLineReceived) get standardOutput as String return _standardOutput.toString get errorOutput as String return _errorOutput.toString get combinedOutput as String return _combinedOutput.toString def _outputLineReceived(sender as Object?, line as DataReceivedEventArgs?) if line.data is nil, return # sometimes this event is triggered with a nil line _standardOutput.append(line.data) _standardOutput.append(Environment.newLine) _combinedOutput.append(line.data) _combinedOutput.append(Environment.newLine) def _errorLineReceived(sender as Object?, line as DataReceivedEventArgs?) if line.data is nil, return # sometimes this event is triggered with a nil line _errorOutput.append(line.data) _errorOutput.append(Environment.newLine) _combinedOutput.append(line.data) _combinedOutput.append(Environment.newLine) def cleanUp if _process ignore _process.outputDataReceived, DataReceivedEventHandler(ref _outputLineReceived) ignore _process.errorDataReceived, DataReceivedEventHandler(ref _errorLineReceived) _process = nil