PowerShell中使用WebClient 下载文件并获取下载进度
前言:因为项目的需要,使用了PowerShell脚本下载指定的安装包并进行安装,配置处理,在PowerShell脚本中使用了.Net的WebClient进行了文件下载操作,但因为需求问题需要从WebClient中获取下载的进度信息,查找了许久,最后经热心网友:Matrix Xu的指点找到了Register-ObjectEvent这个订阅的方法。
以下是个人对订阅事件的一些见解:
PowerShell中提供订阅事件的一些相关接口:Register-ObjectEvent 、Register-EngineEvent 、Register_WmiEvent等相关接口。
Register-ObjectEvent : 可以订阅由.Net对象生成的事件,比如订阅.Net的WebClient对象的下载完成处理,我们可以通过以下代码实现:
1 2 3 4 5 |
|
Register-EngineEvent:可以订阅由PowerShell以及New-Event生成的事件。比如我们需要在PowerShell结束后做一些释放、删除临时文件等的操作,我们可以通过以下代码实现:
1 2 3 4 5 6 |
|
Register-WmiEvent:可以订阅本地计算机或远程jisuanji 上的WMI事件。比如我们需要记录计算机进程启动一些相关信息,我们可以通过以下代码实现
1 2 3 4 |
|
下面附带一个简单的订阅WebClient 进度信息的一个例子:
#==============================全局变量区=========================#
[bool]$isDownloaded=$False
#==============================下载函数===========================#
Function Download([String]$url, [String]$fullFileName)
{
if([String]::IsNullOrEmpty($url) -or [String]::IsNullOrEmpty($fullFileName))
{
return $false;
}
try
{
$client = New-Object System.Net.WebClient
$client.UseDefaultCredentials = $True
#监视WebClient 的下载完成事件
Register-ObjectEvent -InputObject $client -EventName DownloadFileCompleted `
-SourceIdentifier Web.DownloadFileCompleted -Action {
#下载完成,结束下载
$Global:isDownloaded = $True
}
#监视WebClient 的进度事件
Register-ObjectEvent -InputObject $client -EventName DownloadProgressChanged `
-SourceIdentifier Web.DownloadProgressChanged -Action {
#将下载的进度信息记录到全局的Data对象中
$Global:Data = $event
}
$Global:isDownloaded =$False
#监视PowerShell退出事件
Register-EngineEvent -SourceIdentifier ([System.Management.Automation.PSEngineEvent]::Exiting) -Action {
#PowerShell 结束事件
Unregister-Event -SourceIdentifier WebClient.DownloadProgressChanged
Unregister-Event -SourceIdentifier WebClient.DownloadFileComplete
Unregister-Event -SourceIdentifier Timer.Output
}
#启用定时器,设置1秒一次输出下载进度
$timer = New-Object timers.timer
# 1 second interval
$timer.Interval = 1000
#Create the event subscription
Register-ObjectEvent -InputObject $timer -EventName Elapsed -SourceIdentifier Timer.Output -Action {
$percent = $Global:Data.SourceArgs.ProgressPercentage
$totalBytes = $Global:Data.SourceArgs.TotalBytesToReceive
$receivedBytes = $Global:Data.SourceArgs.BytesReceived
If ($percent -ne $null) {
#这里你可以选择将进度显示到命令行 也可以选择将进度写到文件,具体看自己需求
#我这里选择将进度输出到命令行
Write-Host "当前下载进度:$percent 已下载:$receivedBytes 总大小:$totalBytes"
}
}
$timer.Enabled = $True
#使用异步方式下载文件
$client.DownloadFileAsync($url, $fullFileName)
While (-Not $isDownloaded)
{
#等待下载线程结束
Start-Sleep -m 100
}
$timer.Enabled = $False
#清除监视
Unregister-Event -SourceIdentifier WebClient.DownloadProgressChanged
Unregister-Event -SourceIdentifier WebClient.DownloadFileComplete
Unregister-Event -SourceIdentifier Timer.Output
$client.Dispose()
Remove-Variable client
Remove-Variable eventDataComplete
Remove-Variable eventDataProgress
Write-Host "Finish "
}
catch
{
return $false;
}
return $true;
}
上一篇: linux之父是谁
下一篇: python3是什么
推荐阅读