Есть ли способ отслеживать ход загрузки с помощью объекта WebClient в powershell?

Я загружаю файл, используя простую строку:

$webclient = New-Object -TypeName System.Net.WebClient
$webclient.DownloadFile("https://www.example.com/file", "C:/Local/Path/file")

Проблема в том, что я хочу отобразить сообщение пользователю во время загрузки с помощью всплывающего окна или индикатора выполнения в оболочке. Можно ли сделать всплывающее окно, которое исчезает после завершения загрузки, или индикатор выполнения, отслеживающий ход загрузки?


person EGr    schedule 29.01.2014    source источник
comment
Если вы можете выполнить обновление до версии 3, вы можете использовать встроенную команду Invoke-WebRequest https://www.site.com/file -OutFile C:/Local/Path/file, и она автоматически отобразит прогресс.   -  person Keith Hill    schedule 29.01.2014


Ответы (2)


Чтобы отобразить индикатор загрузки файлов, ознакомьтесь с записью в блоге Джейсона Нивера:

Загрузка файлов из Интернета в Power Shell (с прогрессом)

По сути, вы можете создать функцию, которая по-прежнему использует функциональность веб-клиента, но включает способ захвата состояния. Затем вы можете отобразить статус для пользователя, используя функциональность оболочки Write-Progress Power.

function DownloadFile($url, $targetFile)

{

   $uri = New-Object "System.Uri" "$url"

   $request = [System.Net.HttpWebRequest]::Create($uri)

   $request.set_Timeout(15000) #15 second timeout

   $response = $request.GetResponse()

   $totalLength = [System.Math]::Floor($response.get_ContentLength()/1024)

   $responseStream = $response.GetResponseStream()

   $targetStream = New-Object -TypeName System.IO.FileStream -ArgumentList $targetFile, Create

   $buffer = new-object byte[] 10KB

   $count = $responseStream.Read($buffer,0,$buffer.length)

   $downloadedBytes = $count

   while ($count -gt 0)

   {

       $targetStream.Write($buffer, 0, $count)

       $count = $responseStream.Read($buffer,0,$buffer.length)

       $downloadedBytes = $downloadedBytes + $count

       Write-Progress -activity "Downloading file '$($url.split('/') | Select -Last 1)'" -status "Downloaded ($([System.Math]::Floor($downloadedBytes/1024))K of $($totalLength)K): " -PercentComplete ((([System.Math]::Floor($downloadedBytes/1024)) / $totalLength)  * 100)

   }

   Write-Progress -activity "Finished downloading file '$($url.split('/') | Select -Last 1)'"

   $targetStream.Flush()

   $targetStream.Close()

   $targetStream.Dispose()

   $responseStream.Dispose()

}

Тогда вы просто вызовете функцию:

downloadFile "http://example.com/largefile.zip" "c:\temp\largefile.zip"

Кроме того, вот несколько других примеров Write-Progress от docs.microsoft для powrshell 7.

Запись -Прогресс

person SoftwareCarpenter    schedule 29.01.2014
comment
Я знаю о write-progress; однако я не думаю, что есть какой-либо способ увеличить счетчик, чтобы показать ход загрузки. - person EGr; 29.01.2014
comment
Эта функция намного медленнее, чем просто прямой вызов загрузки. Но если вы измените размер буфера на 1000 КБ, это будет иметь ОГРОМНОЕ значение. С буфером в 10 КБ загрузка файла размером 300 МБ заняла 392 секунды. При 1000 КБ это заняло всего 43 секунды. Идеальный размер может варьироваться в зависимости от размера файла и скорости соединения, но 10 КБ, вероятно, мало для большинства загрузок. - person Grant; 07.06.2019
comment
Ваша ссылка Write-Progress больше не действительна - person Gwasshoppa; 23.06.2020
comment
@Gwasshoppa спасибо! Обновлено по ссылке Microsoft. docs.microsoft. com/en-us/powershell/module/ - person SoftwareCarpenter; 24.06.2020
comment
Ссылка на блог Джейсона Нивера не работает - person codeulike; 14.11.2020

В V2 вы можете просто использовать модуль BitsTransfer, например:

Import-Module BitsTransfer
Start-BitsTransfer https://www.example.com/file C:/Local/Path/file
person Keith Hill    schedule 29.01.2014
comment
Имейте в виду, что BITS использует только свободную полосу пропускания сети. - person Ci3; 24.03.2015
comment
Обратите внимание, что это не работает, если вы хотите использовать свой скрипт в запланированной задаче. - person Sebazzz; 04.04.2017
comment
Почему это не будет работать при запуске в запланированной задаче? Если вы уверены, вы нашли способ проверить? Код, который будет запускаться с использованием передачи битов при запуске вручную, но использует другой метод при запуске через запланированное задание? - person karezza; 28.04.2017