欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

PowerShell中使用WebClient 下载文件并获取下载进度

程序员文章站 2022-03-09 12:14:43
...

        前言:因为项目的需要,使用了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-ObjectEvent -InputObject $client -EventName DownloadFileCompleted `

        -SourceIdentifier Web.DownloadFileCompleted -Action {  

             Write-Host "Downloa

dFileCompleted"

            $Global:isDownloaded = $True

        }

 

 

Register-EngineEvent:可以订阅由PowerShell以及New-Event生成的事件。比如我们需要在PowerShell结束后做一些释放、删除临时文件等的操作,我们可以通过以下代码实现:

 

1

2

3

4

5

6

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

           }

 

 

Register-WmiEvent:可以订阅本地计算机或远程jisuanji 上的WMI事件。比如我们需要记录计算机进程启动一些相关信息,我们可以通过以下代码实现

 

1

2

3

4

register-wmiEvent -class 'Win32_ProcessStartTrace' -sourceIdentifier "ProcessStarted" -action {

             #处理进程启动相关事件

             get-history | where { $_.commandline -like "*start-process*" } | export-cliXml "commandHistory.clixml"

}

 

 

下面附带一个简单的订阅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;
}
相关标签: PowerShell

上一篇: linux之父是谁

下一篇: python3是什么