标题: [问题求助] 请求大佬完善并行下载器PowerShell代码 [打印本页]
作者: 小白龙 时间: 2024-9-18 20:19 标题: 请求大佬完善并行下载器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()
复制代码
作者: flashercs 时间: 2024-9-18 23:53
powershell对多线程有限制,用curl.exe --parallel更快- Add-Type -Path .\Downloader.dll
-
- $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
- # 创建 DownloadConfiguration 实例并设置属性
- $downloadConfig = [Downloader.DownloadConfiguration]@{
- ChunkCount = 4
- ParallelDownload = $true
- }
- # 创建DownloadService
- $downloadService = [Downloader.DownloadService]::new($downloadConfig)
- # Register object event listener
- Register-ObjectEvent -InputObject $downloadService -EventName DownloadProgressChanged -SourceIdentifier downloadService.DownloadProgressChanged -Action {
- #$EventArgs.ProgressPercentage|Out-Host
- $percent = [Math]::Truncate($EventArgs.ProgressPercentage * 100) -as [int]
- Write-Progress -Activity "downloading:$($EventArgs.ProgressId)" -Status ("{0:F0}% Completed:" -f $percent) -Id 2 -PercentComplete $percent -CurrentOperation $EventArgs.ProgressId
- }
- Register-ObjectEvent -InputObject $downloadService -EventName ChunkDownloadProgressChanged -SourceIdentifier downloadService.ChunkDownloadProgressChanged -Action {
- #$EventArgs.ProgressPercentage|Out-Host
- $percent = [Math]::Truncate($EventArgs.ProgressPercentage * 100) -as [int]
- Write-Progress -Activity "downloading:$($EventArgs.ProgressId)" -Status ("{0:F0}% Completed:" -f $percent) -ParentId 2 -PercentComplete $percent -CurrentOperation $EventArgs.ProgressId
- }
- # 下载tim.exe
- $task1 = $downloadService.DownloadFileTaskAsync($url_TIM, ".\download\tim.exe")
- $awaiter = $task1.GetAwaiter()
- while (-not $awaiter.IsCompleted) { Start-Sleep -Milliseconds 200; }
- Unregister-Event -SourceIdentifier *
复制代码
作者: Five66 时间: 2024-9-19 01:28
往下载对象里订阅添加
DownloadStarted
ChunkDownloadProgressChanged
DownloadProgressChanged
DownloadFileCompleted
这四个事件(参考示例源码,在事件里写进度条代码)
我脑子不好,不会弄进度条这些特效代码,反正那源码用的是ShellProgressBar,你可以试试http://www.nuget.org/packages/ShellProgressBar/
作者: 小白龙 时间: 2024-9-19 06:21
回复 2# flashercs
多谢大佬, powershell不是支持并行处理吗?
我用gpt生成了如下代码, 能执行成功, 但是没有进度条, 发现gpt还是不够智能, N多轮才能搞成- # 定义文件的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')
-
- # 创建一个存储作业的数组
- $jobs = @()
-
- # 启动并行下载作业
- foreach ($url in $urls) {
- $fileName = Split-Path $url -Leaf
- $outputPath = Join-Path $desktop $fileName
-
- $jobs += Start-Job -ScriptBlock {
- param($downloadUrl, $savePath)
- Invoke-WebRequest -Uri $downloadUrl -OutFile $savePath
- } -ArgumentList $url, $outputPath
- }
-
- # 等待所有作业完成
- $jobs | ForEach-Object {
- Wait-Job $_
- Remove-Job $_
- }
-
- Write-Host "所有文件下载完成!"
复制代码
作者: 小白龙 时间: 2024-9-19 06:23
回复 2# flashercs
用 curl.exe --parallel 在gpt中死活就是搞不成功, ai还是太弱智了, 哎- # 定义文件的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')
-
- # 使用 curl.exe 并行下载,重定向输出到 $null 以避免 PowerShell 处理输出内容
- & curl.exe --parallel `
- --output "$desktop\WeChatSetup.exe" $urls[0] `
- --output "$desktop\QQ_9.9.15.exe" $urls[1] `
- --output "$desktop\TIM3.5.0.exe" $urls[2] `
- *> $null
复制代码
作者: 小白龙 时间: 2024-9-19 06:37
回复 3# Five66
我脑子更不好使, 完全看不懂, 大佬如果懂原理, 用gpt估计能搞出来, 我不行, gpt不听我使唤
作者: 小白龙 时间: 2024-9-19 06:47
回复 2# flashercs
我的想法是, 进度条是字符的那种, 就像用python命令行安装某些库的那种进度, 在powershell控制台中显示的, 不是图形化的那种进度条
作者: flashercs 时间: 2024-9-19 07:45
回复 7# 小白龙
powershell进度条不是控制台字符,而是图形化的.
作者: 小白龙 时间: 2024-9-19 09:56
回复 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 "所有文件下载完成!"
复制代码
作者: 小白龙 时间: 2024-9-19 11:21
回复 8# flashercs
用curl.exe同时下载, 真是有点奇怪, 经常下载weixin.exe是0字节, 为什么呢
作者: flashercs 时间: 2024-9-19 12:00
回复 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 -
复制代码
作者: 小白龙 时间: 2024-9-19 13:51
回复 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>
作者: 小白龙 时间: 2024-9-19 13:55
回复 11# flashercs
感觉用curl代码的--parallel不太通用, 不如用start启动多个下载通用, 但就是不稳定, 很多时候体积大的文件无法下载, 只下载一个0k的文件
作者: jyswjjgdwtdtj 时间: 2024-9-19 17:22
所以不用powershell拉倒 直接写c#不是更好吗
作者: 小白龙 时间: 2024-9-19 21:24
回复 14# jyswjjgdwtdtj
怎样写? powershell中可以嵌入C#吧?
作者: 小白龙 时间: 2024-9-19 21:26
回复 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
作者: jyswjjgdwtdtj 时间: 2024-9-19 22:09
回复 15# 小白龙
单纯cs 没有powershell
.net有system.tasks.parellel并行操作
有net类下载 哪个不比命令行管道输入输出稳定可靠 安全有效
思维不能按着bat里面向for编程那一套来
作者: 小白龙 时间: 2024-9-22 21:25
回复 11# flashercs
大佬, 想请教一下, 这个代码怎样加出错的判断呢? 用 if (-not $?) 不灵
作者: flashercs 时间: 2024-9-23 12:05
回复 18# 小白龙 复制代码
作者: Five66 时间: 2024-9-23 23:07
粒度要求不高的话,直接用 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 pause
复制代码
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |