粒度要求不高的话,直接用 System.Net.WebClient 的 DownloadFileAsync 实例方法就能异步下载
而且 WebClient 的 DownloadProgressChanged 事件中可以获取下载大小和百分比等信息
只是控制台的输出不像窗口那样自由,加上powershell那些坑爹的设定,单个的进度条还好,多个的就麻烦了
总之可以试试参考下面的 | | | | | $uris=@( | | "https://dldir1v6.qq.com/weixin/Windows/WeChatSetup.exe" | | "https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240902_x64_01.exe" | | "https://dldir1.qq.com/qqfile/qq/TIM3.5.0/TIM3.5.0.22143.exe" | | ) | | | | $path = "$home\Desktop\weixin.exe" | | $dir = "$home\Desktop" | | $wc=[collections.arraylist]::new($uris.length) | | $str=[collections.arraylist]::new($uris.length) | | $done=[collections.arraylist]::new($uris.length) | | $uris |foreach { | | $wc.add([System.Net.WebClient]::new()); | | $str.add('0#0#0#'); | | $done.add($false) | | }|out-null | | | | $charpro={ | | $i=0;$j=0;$uris |foreach { | | [console]::write($uris[$j].split('/')[-1]); | | $s=$str[$j].split('#') | | [console]::writeline(' {0}/{1}',[int64]([int64]$s[0]*[int64]$s[1]/100),$s[0]) | | $l=[int](($cw-8)*[int]$s[1]/100) | | [console]::writeline('[{0}{1}] {2}%','='*$l,' '*($cw-8-$l),$s[1]) | | $i+=2;$j+=1 | | }|out-null | | } | | | | $evt1={ | | '$index='+$args[0]+';'+' | | #$evArgs=$event.SourceEventArgs; | | #write-host ($EventArgs.TotalBytesToReceive+"#"+$EventArgs.ProgressPercentage+"#"+$EventArgs.BytesReceived+"#") | | $str[$index]=""+$EventArgs.TotalBytesToReceive+"#"+$EventArgs.ProgressPercentage+"#"+$EventArgs.BytesReceived+"#"; | | $null;' | | } | | | | $evt2={"`$index=$args;"+'$done[$index]=$true'} | | | | $i=0;$wc |foreach { | | register-objectevent -InputObject $_ -EventName 'DownloadProgressChanged' -SourceIdentifier ('DlProCh'+$i) -Action ([scriptblock]::create($evt1.invoke($i,$uris.length))) | | register-objectevent -InputObject $_ -EventName 'DownloadFileCompleted' -SourceIdentifier ('DlComp'+$i) -Action ([scriptblock]::create($evt2.invoke($i))) | | $i+=1 | | }|out-null | | | | $i=0;$wc |foreach {$_.DownloadFileAsync($uris[$i],$dir+'\'+$uris[$i].split('/')[-1]);$i+=1} | | | | [console]::CursorVisible=$false | | '';'';while($true){ | | $cl=[console]::CursorLeft | | $ct=[console]::CursorTop | | $cw=[console]::WindowWidth | | $charpro.invoke() | | [console]::SetCursorPosition($cl,$ct) | | if(($done|where{$_}).length -eq $uris.length){ | | $charpro.invoke() | | break | | } | | } | | [console]::CursorVisible=$true | | cmd /c pauseCOPY |
|