Reputation: 486
I have a script that's calling an external exe file, msdl.exe, which is a multi-protocol downloader for various streaming protocols that I've compiled for windows.
It's output while downloading looks like this:
download [ MechHand-1.wmv ]
Host: [ 132.68.3.150:554 ] connected!
Host: [ 132.68.3.150:554 ] connected!
Speed: 2.000
DL: 815061/313870475 B -- 0% 150.2K/s # this line updates
The line I use to call the exe from within the script is:
cmd /c .\msdl.exe -s2 $address -o $filename '2>&1'
I've compiled the script to an exe to run on client computers. When running as an exe, however, the progress line does not overwrite itself, instead it's a new line every time, like so:
download [ MechHand-1.wmv ]
Host: [ 132.68.3.150:554 ] connected!
Host: [ 132.68.3.150:554 ] connected!
Speed: 2.000
DL: 82992/313870475 B -- 0% 0B/s
DL: 158076/313870475 B -- 0% 158.1K/s
DL: 233160/313870475 B -- 0% 158.1K/s
DL: 301987/313870475 B -- 0% 143.9K/s
DL: 377071/313870475 B -- 0% 143.9K/s
What I think I need is to pipe the output of the command executing msdl.exe into a foreach loop, and based on the content of the line either print it regularly (like the line saying download [ filename ]) or overwrite the previous line.
However if I pipe the output my concern is that it will first run the command, which could take a long time based on file size, and then display the progress all at once when it is over, rather than display output while it is being generated.
Would this work, or how can I replicate the desired behavior?
PS: The stderr redirection is because MSDL writes to stderr, and while this doesn't matter when running the script, when running the exe each line is printed in red and prefixed with 'ERROR: '.
Upvotes: 0
Views: 130
Reputation: 10054
First, can you drop the call to cmd
and just execute in PowerShell? Second, pipe the output into a ForEach-Object
loop, and each time there is output clear the host and just display what you want to display. For example you could save the first 5 lines as a in banner variable. Then you could display the banner and the output line.
& .\msdl.exe -s2 $address -o $filename | ForEach-Object {$i=0} {
Clear-Host
$Banner
if ($i -le 5) {
$Banner += $_
}
$_
$i++
}
Upvotes: 1