GUI 中的 Powershell Write-Progress 命令在完成之前立即停止

Powershell Write-Progress Command in GUI stops right before it is finished

我使用的代码在独立模式下工作得很好,但现在我把它放到一个按钮中它就停止了。 例如我有 400571 行,我在其中寻找匹配项,进度条停在第 400000 行,因为我告诉他每 1000 行更新一次写入进度以提高性能。

我很确定临界点必须是 if($i % 1000 -eq 0) 因为如果我将它降低到 10 他会停在 400570 并且仍然不完成,但我不想将它设置为 1 , 因为每行刷新进度条会占用更多时间。

按钮中包含的代码是:

$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(30,10)
$OKButton.Size = New-Object System.Drawing.Size(300,92)
$OKButton.Text = "Filtern"
$OKButton.Name = "Filter"
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::None
$OKButton.Add_Click({$i= 0
$path = "C:\temp\smtpfilter\LNS5filter.txt"
$length = (Get-Content $path).Length

#Datum, Hostname und Message Nummer
$result = Get-Content $path | ForEach-Object {
    if($_ -match '(\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}).*\(((?:\d{1,3}\.){3}\d{1,3})\) disconnected\.?\s+(\d+) message\[s\]'){
        try {
            #$dns = [System.Net.Dns]::GetHostEntry($matches[2]).HostName
        }
        catch { 
            #$dns = 'Not available' 
        }
        [PsCustomObject]@{
            IP       = $matches[2]
            Messages = [int]$matches[3]
            #DNSName  = $dns
            Date     = [datetime]::ParseExact($matches[1], 'dd.MM.yyyy HH:mm:ss', $null)
        }
        $i++
    if($i % 1000 -eq 0){
        Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length)  * 100)
    }
 }}

 #Messages Counted
 $cumulative = $result | Group-Object -Property IP | ForEach-Object {
    [PsCustomObject]@{
        IP = $_.Name
        Messages = ($_.Group | Measure-Object -Property Messages -Sum).Sum
        #DNSName = $_.Group[0].DNSName
        Date    = ($_.Group | Sort-Object Date)[-1].Date
    }
}})
$objForm.Controls.Add($OKButton)

(我 # dns 命令,因为我现在远程工作,解析名称需要很长时间)

你的 foreach-object 运行 400571 次 - 你只是在迭代 400000 时停止更新进度条。

如果您在 foreach 对象完成后再次更新进度条,您将神奇地 100% 完成...

$result = Get-Content $path | ForEach-Object {
 ...
 }}

# final update to progress bar with total items processed
Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length)  * 100)

#Messages Counted
$cumulative = ...

更新

您还需要将计数器逻辑移到 if 子句之外,否则您只会计算已处理的 匹配 记录的数量...

$result = Get-Content $path | ForEach-Object {
    if($_ -match '(\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}).*\(((?:\d{1,3}\.){3}\d{1,3})\) disconnected\.?\s+(\d+) message\[s\]'){
        ...
        # move these lines out from the "if( $_ -match ..."
        $i++
        if($i % 1000 -eq 0)
        {
            Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length)  * 100)
        }
    }
}

变成

$result = Get-Content $path | ForEach-Object {

    if($_ -match '(\d{2}\.\d{2}\.\d{4} \d{2}:\d{2}:\d{2}).*\(((?:\d{1,3}\.){3}\d{1,3})\) disconnected\.?\s+(\d+) message\[s\]')
    {
        ...
    }

    # now we're counting *every* record, not just the ones that match
    $i++
    if( $i % 1000 -eq 0 )
    {
        Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length)  * 100)
    }

}

# final update to progress bar with total items processed
Write-Progress -activity "Searching for matches" -status "Scanned: $i of $($length)" -percentComplete (($i / $length)  * 100)

...