返回列表 发帖

[问题求助] 请求大佬完善并行下载器PowerShell代码

我在github找到一个C#的并行下载器组件, 使用下面的代码可以成功下载weixin,
但是我想同时,并行下载: 微信 + QQ + TIM, 并且有三个软件下载的进度条显示, 就像开源页中演示的那样的效果, 不用像它那样复杂, 有几个文件需要下载, 就显示几个进度条就行了
请求大佬支招, 多谢

开源地址:
https://github.com/bezzad/Downloader

多线下载进度条演示, 用右键从新标签页打开图片:



先下载.net 4.62的dll: https://www.nuget.org/api/v2/package/Downloader/3.1.2
Add-Type -Path $PSScriptRoot\Downloader.dll
# 创建 DownloadBuilder 实例
$downloadBuilder = [Downloader.DownloadBuilder]::New()
$url_WX = "https://dldir1v6.qq.com/weixin/Windows/WeChatSetup.exe" #微信
$url_QQ = "https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240902_x64_01.exe" #QQ
$url_TIM = "https://dldir1.qq.com/qqfile/qq/TIM3.5.0/TIM3.5.0.22143.exe" #TIM
$path = "$home\Desktop\weixin.exe"  # 确保这是一个完整的文件路径
$dir = "$home\Desktop"
# 创建 DownloadConfiguration 实例并设置属性
$downloadConfig = [Downloader.DownloadConfiguration]@{
    ChunkCount = 1
    ParallelDownload = $true
}
# 配置下载
$downloadBuilder = $downloadBuilder.WithUrl($url_WX)
$downloadBuilder = $downloadBuilder.WithDirectory($dir)
$downloadBuilder = $downloadBuilder.WithConfiguration($downloadConfig)
$downloadBuilder = $downloadBuilder.WithFileLocation($path)
# 构建下载对象
$download = $downloadBuilder.Build()
# 异步开始下载
$awaiter = $download.StartAsync().GetAwaiter()
$awaiter.GetResult()COPY

粒度要求不高的话,直接用 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" #QQ
"https://dldir1.qq.com/qqfile/qq/TIM3.5.0/TIM3.5.0.22143.exe" #TIM
)
$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

TOP

回复 18# 小白龙
if($LASTEXITCODE -ne 0)COPY
微信:flashercs
QQ:49908356

TOP

回复 11# flashercs


    大佬, 想请教一下, 这个代码怎样加出错的判断呢? 用 if (-not $?) 不灵

TOP

回复 15# 小白龙

单纯cs 没有powershell
.net有system.tasks.parellel并行操作
有net类下载 哪个不比命令行管道输入输出稳定可靠 安全有效
思维不能按着bat里面向for编程那一套来
你好

TOP

回复 11# flashercs


    大佬, 我查了一些资料, 下面是官方链接和示例, 是不是上面的代码中要添加 --parallel-max 10?

curl 从版本 7.66.0 开始支持 --parallel 和 --parallel-max 选项,允许并行下载多个文件。
https://daniel.haxx.se/blog/2019 ... p-3-future-is-here/

并行下载示例:
curl --parallel --parallel-max 10 -O http://example.com/file1 -O http://example.com/file2

TOP

回复 14# jyswjjgdwtdtj


   怎样写? powershell中可以嵌入C#吧?

TOP

所以不用powershell拉倒 直接写c#不是更好吗
你好

TOP

回复 11# flashercs


  感觉用curl代码的--parallel不太通用, 不如用start启动多个下载通用, 但就是不稳定, 很多时候体积大的文件无法下载, 只下载一个0k的文件

TOP

回复 11# flashercs


    我的curl版本是7.79也报错, 但是能下载
-----------------------------------------------------版本:
C:\Users\Administrator>curl -V
curl 7.79.1 (Windows) libcurl/7.79.1 Schannel
Release-Date: 2021-09-22
Protocols: dict file ftp ftps http https imap imaps pop3 pop3s smtp smtps telnet tftp
Features: AsynchDNS HSTS IPv6 Kerberos Largefile NTLM SPNEGO SSL SSPI UnixSockets
-------------------------------------------------------报错:
curl.exe : Warning: <stdin>:4: warning: '--compressed' the installed libcurl version
所在位置 行:31 字符: 5
+ } | & $curl --config -
+     ~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (Warning: <stdin...ibcurl version :String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError

Warning: doesn't support this
Warning: <stdin>:11: warning: '--compressed' the installed libcurl version
Warning: doesn't support this
DL% UL%  Dled  Uled  Xfers  Live   Qd Total     Current  Left    Speed
--  --      0     0     2     2     0 --:--:-- --:--:-- --:--:--     0      
  7 --  21.4M     0     2     2     0  0:00:06 --:--:--  0:00:05 42.6M      
15 --  42.9M     0     2     2     0  0:00:06  0:00:01  0:00:05 42.7M      
23 --  64.3M     0     2     2     0  0:00:06  0:00:01  0:00:04 42.7M      
31 --  85.8M     0     2     2     0  0:00:06  0:00:02  0:00:04 42.7M      
39 --   107M     0     2     2     0  0:00:06  0:00:02  0:00:03 42.7M      
47 --   128M     0     2     2     0  0:00:06  0:00:03  0:00:03 42.7M      
55 --   150M     0     2     2     0  0:00:06  0:00:03  0:00:02 42.8M      
62 --   171M     0     2     1     0  0:00:06  0:00:04  0:00:02 42.8M      
70 --   192M     0     2     1     0  0:00:06  0:00:04  0:00:01 42.8M      
78 --   214M     0     2     1     0  0:00:06  0:00:05  0:00:01 42.8M      
86 --   235M     0     2     1     0  0:00:06  0:00:05 --:--:-- 42.8M      
94 --   257M     0     2     1     0  0:00:06  0:00:06 --:--:-- 42.8M      
100 --   272M     0     2     0     0  0:00:06  0:00:06 --:--:-- 42.8M     

PS C:\Windows\System32\WindowsPowerShell\v1.0>

TOP

回复 10# 小白龙
# curl.exe路径,7.76+才支持--parallel
$curl = "curl.exe"
# 定义文件的URL和保存路径
$downloads = @(
  @{
    src  = "https://dldir1.qq.com/qqfile/qq/TIM3.5.0/TIM3.5.0.22143.exe"
    dest = "$home\downloads\tim.exe"
  }
  @{
    src  = "https://dldir1.qq.com/qqfile/qq/QQNT/Windows/QQ_9.9.15_240902_x64_01.exe"
    dest = "$home\downloads\qq.exe"
  }
)
$begin = $true
$downloads | ForEach-Object {
  if ($begin) {
    $begin = $false
  } else {
    '--next'
  }
  '--url "{0}"' -f $_.src
  '--output "{0}"' -f ($_.dest.Replace('\', '\\'))
  '--location'
  '--compressed'
  '--tr-encoding'
  '--globoff'
} -End {
  '--parallel'
} | & $curl --config -COPY
微信:flashercs
QQ:49908356

TOP

回复 8# flashercs


    用curl.exe同时下载, 真是有点奇怪, 经常下载weixin.exe是0字节, 为什么呢

TOP

回复 8# flashercs


    大佬, 刚刚用了下面的方法, 发现很多时候weixin.exe下载后的文件为0字节, 其它两个文件下载就没事, 看来curl下载不稳定啊, 另外gpt说 curl.exe --parallel没有这个参数
# 定义文件的URL和保存路径
$urls = @(
    "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"
)
# 获取桌面路径
$desktop = [System.Environment]::GetFolderPath('Desktop')
# 创建一个存储进程的数组
$processes = @()
# 启动并行下载进程
foreach ($url in $urls) {
    $fileName = Split-Path $url -Leaf
    $outputPath = Join-Path $desktop $fileName
    $process = Start-Process -FilePath "curl.exe" `
        -ArgumentList "--output `"$outputPath`" `"$url`"" `
        -PassThru #-NoNewWindow
    $processes += $process
}
# 等待所有进程完成
$processes | ForEach-Object {
    $_.WaitForExit()
}
Write-Host "所有文件下载完成!"COPY

TOP

回复 7# 小白龙

powershell进度条不是控制台字符,而是图形化的.
微信:flashercs
QQ:49908356

TOP

回复 2# flashercs


    我的想法是, 进度条是字符的那种, 就像用python命令行安装某些库的那种进度, 在powershell控制台中显示的, 不是图形化的那种进度条

TOP

返回列表