重新创建Write-Progress功能

时间:2017-05-23 19:56:17

标签: powershell

我有一个脚本调用外部exe文件msdl.exe,这是我为windows编译的a multi-protocol downloader for various streaming protocols

下载时的输出如下:

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

我用来从脚本中调用exe的行是:

cmd /c .\msdl.exe -s2 $address -o $filename '2>&1'

我已将脚本编译为exe以在客户端计算机上运行。 但是,当作为exe运行时,进度线不会覆盖自身,而是每次都是一个新行,如下所示:

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

我认为我需要的是将执行msdl.exe的命令的输出传递到foreach循环中,并根据该行的内容定期打印它(如说明下载[filename]的行)或覆盖上一行。

然而,如果我管道输出我的担心是它将首先运行命令,这可能需要很长时间基于文件大小,然后在它结束时立即显示进度,而不是显示输出正在生成。

这是否有效,或者我如何复制所需的行为?

PS:stderr重定向是因为MSDL写入stderr,虽然这在运行脚本时无关紧要,但在运行exe时,每一行都以红色打印并以“ERROR:”为前缀。

1 个答案:

答案 0 :(得分:1)

首先,您可以将调用放到cmd并在PowerShell中执行吗?其次,将输出传递到ForEach-Object循环,每次有输出清除主机并显示您想要显示的内容。例如,您可以将前5行保存为横幅变量。然后你可以显示横幅和输出线。

& .\msdl.exe -s2 $address -o $filename | ForEach-Object {$i=0} {
   Clear-Host
   $Banner 
   if ($i -le 5) {
        $Banner += $_
   }
   $_
   $i++
}