Войти

Показать полную графическую версию : Добавить прогресс бар к скрипту скачивания файлов из интернета


Uragan66
30-06-2019, 19:58
Добрый день всем!
Написал коротенький скрипт для скачивания плейлистов:
foreach($line in Get-Content downl.txt) {
if($line ){
$webclient = New-Object System.Net.WebClient
$webclient.Encoding = [System.Text.Encoding]::UTF8
$webclient.DownloadString($line) | Out-File .\out\out.m3u -Append
}
}
Скрипт берёт ссылки из файла downl.txt (прикреплён) и скачивает все плейлисты в один out.m3u
Хотелось бы добавить к скрипту прогресс бар, заполняющийся по мере скачивания плейлистов.
Нашел код неплохого прогресс бара с GUI:
$Path = "F:\zagruz" ## --- Put Folder-Path Here
If (Test-Path $Path) {
Write-Host
Write-Host "Listing All Files Found In $Path" -ForegroundColor "Yellow"
Write-Host "=========================================" -ForegroundColor "Yellow"

Add-Type -assembly System.Windows.Forms

## -- Create The Progress-Bar
$ObjForm = New-Object System.Windows.Forms.Form
$ObjForm.Text = "Demonstration of Progress-Bar In PowerShell"
$ObjForm.Height = 100
$ObjForm.Width = 500
$ObjForm.BackColor = "White"

$ObjForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
$ObjForm.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen

## -- Create The Label
$ObjLabel = New-Object System.Windows.Forms.Label
$ObjLabel.Text = "Starting. Please wait ... "
$ObjLabel.Left = 5
$ObjLabel.Top = 10
$ObjLabel.Width = 500 - 20
$ObjLabel.Height = 15
$ObjLabel.Font = "Tahoma"
## -- Add the label to the Form
$ObjForm.Controls.Add($ObjLabel)

$PB = New-Object System.Windows.Forms.ProgressBar
$PB.Name = "PowerShellProgressBar"
$PB.Value = 0
$PB.Style="Continuous"

$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Width = 500 - 40
$System_Drawing_Size.Height = 20
$PB.Size = $System_Drawing_Size
$PB.Left = 5
$PB.Top = 40
$ObjForm.Controls.Add($PB)

## -- Show the Progress-Bar and Start The PowerShell Script
$ObjForm.Show() | Out-Null
$ObjForm.Focus() | Out-NUll
$ObjLabel.Text = "Starting. Please wait ... "
$ObjForm.Refresh()

Start-Sleep -Seconds 1

## -- Execute The PowerShell Code and Update the Status of the Progress-Bar

$Result = Get-ChildItem -Path $Path -File -Recurse -Force | Select Name, @{Name="Path";Expression={$_.FullName}}
$Counter = 0
ForEach ($Item In $Result) {
## -- Calculate The Percentage Completed
$Counter++
[Int]$Percentage = ($Counter/$Result.Count)*100
$PB.Value = $Percentage
$ObjLabel.Text = "Recursive Search: Writing Names of All Files Found Inside $Path"
$ObjForm.Refresh()
Start-Sleep -Milliseconds 150
# -- $Item.Name
"`t" + $Item.Path

}

$ObjForm.Close()
Write-Host "`n"
}
Else {
Write-Host
Write-Host "`t Cannot Execute The Script." -ForegroundColor "Yellow"
Write-Host "`t $Path Does Not Exist in the System." -ForegroundColor "Yellow"
Write-Host
}
Но как его "прикрутить" к своему скрипту, ума не приложу. Нигде не могу найти хотя бы подсказки на эту тему.
Ткните носом, пожалуйста, какие переменные указать в этом скрипте, чтобы он контролировал процесс выполнения моего скрипта.

greg zakharov
01-07-2019, 12:22
Зачем в цикле плодить экземпляры объекта WebClient? Во-вторых, непонятно у вас WinForm сценарий или все должно выводиться в хост? Для последнего предусмотрен командлет Write-Progress, в первом случае - все зависит от того, как именно должен вестись полсчет: скопом для всех файлов или же в отдельности для каждого (хотя в обоих случаях нужно взять размер файла из ответа запроса и относительно него вести расчет процента состояния загрузки).

Busla
01-07-2019, 12:27
Нашел код неплохого прогресс бара с GUI: Но как его "прикрутить" к своему скрипту, ума не приложу.»

1) Прикрутите к своему скрипту штатный прогресс бар
2) Замените вызов штатного прогресс-бара на
$PB.Value = $Percentage
$ObjLabel.Text = "Recursive Search: Writing Names of All Files Found Inside $Path"
$ObjForm.Refresh()

Зачем в цикле плодить экземпляры объекта WebClient? »
чтобы потом обернуть в workflow и получить параллельное исполнение

Uragan66
01-07-2019, 13:11
Зачем в цикле плодить экземпляры объекта WebClient? »
Пробовал прописывать не в цикле - скачивание не идёт.
непонятно у вас WinForm сценарий или все должно выводиться в хост? »
да из меня, честно сказать, скриптописатель пока никакой, но, думаю, лучше сделать сценарием WinForm.
как именно должен вестись полсчет: скопом для всех файлов или же в отдельности для каждого »
Наверное лучше всё вместе, начало работы скрипта - пошла полоска на прогресс баре, скрипт отработал - прогресс бар закрылся. Так как в начале темы я привёл только часть скрипта, после скачивания плейлиста идёт его разбор с кодом, написанным Вами в другой теме ».
Я его только немного подправил для своей задачи (продолжение кода):
$soft = 'nhrt.exe'
Start-Process -FilePath $soft -ArgumentList '-list:cleaning.txt .\out\out.m3u' -NoNewWindow -Wait
@(for($i, $arr = 0, (gc .\out\out.m3u -Encoding utf8); $i -lt $arr.Length;) {
$a, $b = $arr[$i], $arr[$i + 1] # потенциальная пара
# критерий относительно которого формируется пара
if ($a.StartsWith('#EXTINF') -and $b -match ':\/\/') {
# выводим пару в окно хоста
"$a`n$b"
# переходим на две позиции вперед
$i += 2
}
else {
# в противном случае переходим к следующему значению
++$i
continue
}
}) | Sort-Object -Unique | Out-File .\out\plist_google.m3u -Encoding utf8
Start-Process -FilePath $soft -ArgumentList '-list:replzag.txt .\out\plist_google.m3u' -NoNewWindow -Wait
Прикрутите к своему скрипту штатный прогресс бар »
Busla, можно было бы конечно, но хотелось бы поэстетичнее, с красивой формой...

Vadikan
01-07-2019, 14:46
А производительность тестировали? А то бывает и так https://twitter.com/sterkin_ru/status/1103182187162152961

Busla
01-07-2019, 14:57
Vadikan, честно говоря, из твита непонятно: как бывает, и при чём здесь wget неизвестного происхождения.

Vadikan
01-07-2019, 18:01
Busla, там invoke-webrequest, а wget - его псевдоним.




© OSzone.net 2001-2012