当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] Write-Progress:更好的使用方法

作者:精品下载站 日期:2024-12-14 12:38:27 浏览:14 分类:玩电脑

Write-Progress:更好的使用方法


本文将讨论如何使用Powershell Write-Progress。大多数时候,我更喜欢使用 Write-Verbose 显示脚本的工作状态。 Write-Verbose 是将定期消息发送到控制台以让用户知道发生了什么的绝佳方法。这也很好,因为您可以使用内置的 Verbose 开关快速打开和关闭它。

[玩转系统] Write-Progress:更好的使用方法

然而,Write-Verbose 非常简单。这只是控制台的周期性文本显示。没有什么其他的了。有时,您需要更明显和更好的方式来向脚本用户指示脚本的进程进行到什么程度。为此,我使用 Write-Progress Write-Progress cmdlet。

此 Powershell cmdlet 非常适合在控制台中显示图形进度条。这是一种直观的方式,不仅可以向用户显示状态消息,还可以通过进度条向用户指示脚本执行的进度。

[玩转系统] Write-Progress:更好的使用方法

如何使用写入进度 Cmdlet

使用这个 cmdlet 非常简单。最基本的是,您只需使用 Activity 参数指定进度条的标题、使用 Status 参数指定要显示的状态消息以及要填写的内容使用 PercentComplete 参数的进度条。

Write-Progress -Activity 'Title' -Status 'Doing something' -PercentComplete 0

PowerShell 新手可能会看到这一点并立即尝试执行以下操作:

Write-Progress -Activity 'Title' -Status 'Doing something 2' -PercentComplete 25

## Some process here

Write-Progress -Activity 'Title' -Status 'Doing something 3' -PercentComplete 50

## Some process here

Write-Progress -Activity 'Title' -Status 'Doing something 4' -PercentComplete 75

## Some process here

乍一看,您可能没有注意到这里有问题,但请考虑一下这是如何维护的。请注意 PercentComplete 参数。请注意,我必须静态分配值 0、25、50 和 75?除非必要,否则我们永远不想静态编码任何东西。另外,我在这里并没有遵循 DRY 原则,将相同的字符串 Write-Progress -Activity 'Title' -Status 'Doing Something' 重复四次。我们需要重构此代码,以提供一种更动态的方式来指定 PercentComplete 参数并删除尽可能多的代码重复。

为此,我首先需要找到一种方法来避免在每个 Write-Progress 调用中对 PercentComplete 值进行硬编码。为此,我首先需要查明我有多少个 Write-Progress 调用。一旦我弄清楚了这一点,我就可以进行一些算术来获得实际的百分比值。

我可以手动执行此操作,也可以不执行此操作。我选择不。然而,此时它变得有点毛茸茸的。我需要使用 PowerShell 解析器来查找函数本身内部对 Write-Progress 的每个引用。

$steps = ([System.Management.Automation.PsParser]::Tokenize((gc "$PSScriptRoot$($MyInvocation.MyCommand.Name)"), [ref]$null) | where { $_.Type -eq 'Command' -and $_.Content -eq 'Write-Progress' }).Count

现在,添加或删除 Write-Progress 函数调用并不重要。 $steps 将始终包含函数中 Write-Progress 调用的总数。

现在,我们可以通过增加 $stepcounter 变量并从中创建百分比值来动态地将值传递给 PercentComplete

$steps = ([System.Management.Automation.PsParser]::Tokenize($MyInvocation.MyCommand.Definition, [ref]$null) | where { $_.Type -eq 'Command' -and $_.Content -eq 'Write-Progress' }).Count

$stepCounter = 0

Write-Progress -Activity 'Title' -Status 'Doing something' -PercentComplete ((($stepCounter++) / $steps) * 100)

## Some process here

Write-Progress -Activity 'Title' -Status 'Doing something' -PercentComplete ((($stepCounter++) / $steps) * 100)

## Some process here

Write-Progress -Activity 'Title' -Status 'Doing something' -PercentComplete ((($stepCounter++) / $steps) * 100)

## Some process here

伟大的!但这看起来仍然很丑。看看所有的代码重复!是时候构建一个辅助函数了。我现在就建造一个。

function Write-ProgressHelper {
    param(
        [int]$StepNumber,
        [string]$Message
    )
    
    Write-Progress -Activity 'Title' -Status $Message -PercentComplete (($StepNumber / $steps) * 100)
}

现在,我们可以简单地从函数本身内部调用这个辅助函数。

$stepCounter = 0

Write-ProgressHelper -Message 'Doing something' -StepNumber ($stepCounter++)

## Some process here

Write-ProgressHelper -Message 'Doing something2' -StepNumber ($stepCounter++)

## Some process here

Write-ProgressHelper -Message 'Doing something3' -StepNumber ($stepCounter++)

## Some process here

尽管我们仍然有一些代码重复,但我们能够删除其中一些。由于我们将这些 Write-Progress 引用替换为 Write-ProgressHelper,因此我们必须更改代码来查找步骤,因为我们的步骤代码正在查找函数引用名称。

$steps = ([System.Management.Automation.PsParser]::Tokenize((gc "$PSScriptRoot$($MyInvocation.MyCommand.Name)"), [ref]$null) | where { $_.Type -eq 'Command' -and $_.Content -eq 'Write-ProgressHelper' }).Count

这最终给我们留下了这个脚本。

function Write-ProgressHelper {
	param (
	    [int]$StepNumber,
	    [string]$Message
	)

	Write-Progress -Activity 'Title' -Status $Message -PercentComplete (($StepNumber / $steps) * 100)
}

$script:steps = ([System.Management.Automation.PsParser]::Tokenize((gc "$PSScriptRoot$($MyInvocation.MyCommand.Name)"), [ref]$null) | where { $_.Type -eq 'Command' -and $_.Content -eq 'Write-ProgressHelper' }).Count

$stepCounter = 0

Write-ProgressHelper -Message 'Doing something' -StepNumber ($stepCounter++)
Start-Sleep -Seconds 5

## Some process here

Write-ProgressHelper -Message 'Doing something2' -StepNumber ($stepCounter++)

Start-Sleep -Seconds 5

## Some process here

Write-ProgressHelper -Message 'Doing something3' -StepNumber ($stepCounter++)

Start-Sleep -Seconds 5

## Some process here

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯