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)
...
我使用的代码在独立模式下工作得很好,但现在我把它放到一个按钮中它就停止了。 例如我有 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)
...