Hi
I found a number of articles on running processes and BAT files and capturing the output and errors, e.g.
http://www.chinabtp.com/captured-output-of-command-run-by-powershell-is-sometimes-incomplete/
http://stackoverflow.com/questions/24370814/how-to-capture-process-output-asynchronously-in-powershell
So I created a test function below and it "works"
However I wanted to have control over the display of the output, i.e. close to real time. According to the doco the event gets fired for each newline, my tests indicate otherwise.
i.e. the script may run for a long time and have 1000s of lines of output..
I did a test where I told the BAT file to sleep. However the results where not as expected.
There was a delay until the first output occurred, then a further delay which could be accounted for due to the sleep.
https://msdn.microsoft.com/en-us/library/microsoft.powershell.utility.activities.registerobjectevent_methods(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/microsoft.powershell.utility.activities.registerobjectevent_members(v=vs.85).aspx
Don't help because there are poorly documented, e.g. MaxtriggerCount, provides access to maxtriggercount, none of the items are actually described by function.
The C# process has ReadToEnd() but this does not apply to Powershell
So the question :
>> Is there a way for me fetch the output event data, say in the 1s while loop ?
SBS_Logger justs adds the timestamp
Function SBS_RunAProcess { [CmdletBinding()] param( [Parameter(Mandatory = $True)] [String]$Label ) # Setup stdin\stdout redirection $StartInfo = New-Object System.Diagnostics.ProcessStartInfo -Property @{ FileName = "F:\ScriptWork\helloworld.bat" Arguments = $Label UseShellExecute = $false RedirectStandardOutput = $true RedirectStandardError = $true } # Create new process $Process = New-Object System.Diagnostics.Process # Assign previously created StartInfo properties $Process.StartInfo = $StartInfo # Register Object Events for stdin\stdout reading $OutEvent = Register-ObjectEvent -InputObject $Process -EventName OutputDataReceived -Action { SBS_Logger $Event.SourceEventArgs.Data } $ErrEvent = Register-ObjectEvent -InputObject $Process -EventName ErrorDataReceived -Action { SBS_Logger $Event.SourceEventArgs.Data } # Start process [void]$Process.Start() # Begin reading stdin\stdout $Process.BeginOutputReadLine() $Process.BeginErrorReadLine() # Do something else while events are firing do { #Write-Host 'Still alive!' -ForegroundColor Green Start-Sleep -Seconds 1 } while (!$Process.HasExited) # Unregister events $OutEvent.Name, $ErrEvent.Name | ForEach-Object {Unregister-Event -SourceIdentifier $_} }
BAT Content @echo off echo "hello world from a BAT file" echo "args where %1%" rem timeout /t 10 /nobreak > NUL SET === 2015-09-03 14:04:00 Task test_bat running 2015-09-03 14:04:01 "hello world from a BAT file" 2015-09-03 14:04:01 "args where greg" 2015-09-03 14:04:01 ALLUSERSPROFILE=C:\ProgramData 2015-09-03 14:04:01 APPDATA=C:\Users\build\AppData\Roaming ===================== BAT Content echo off echo "hello world from a BAT file" echo "args where %1%" timeout /t 10 /nobreak > NUL SET === 2015-09-03 14:08:43 Task test_bat running 2015-09-03 14:08:54 "hello world from a BAT file" <= 9s delay 2015-09-03 14:08:54 "args where greg" 2015-09-03 14:09:03 ALLUSERSPROFILE=C:\ProgramData <= 9s delay