我有一个基于PowerShell的大型GUI实用程序,可以根据请求在后台运行不同的操作。当他们询问作业的状态时,他们可以通过如下代码看到它们:
Get-Job | foreach {
$JobID = $_.Id
$JobCaption = $script:JobList[$JobID]
if ($JobCaption -ne $null) {
$JobState = $_.JobStateInfo
$JobProgress = $_.Progress
$JobPercent = $JobProgress.PercentComplete
$JobStatusDescription = $JobProgress.StatusDescription
$lstJobStatus.Items.Add("$JobID`: $JobCaption is $JobState ($JobStatusDescription), $JobPercent%")
}
}
这适用于直接作业的任务。但是,有些任务反过来会将子任务作为真正的工作,并围绕它提供一些支持代码。例如:
$Job = Start-Job -ScriptBlock {
# setup omitted
$ijob = Convert-VHD -Path $VHDPath -DestinationPath $NewVHDPath -ComputerName $TargetServer -VHDType Dynamic -ErrorAction 'SilentlyContinue' -AsJob
while ($ijob.State -eq "Running") {
$ip = $ijob.Progress
Write-Progress -Activity $ip.Activity -CurrentOperation $ip.CurrentOperation -PercentComplete $ip.PercentComplete -Status $ip.Status
Start-Sleep -Seconds 5
}
# cleanup omitted
}
注意我有一个长时间运行的操作,所以我从中做了一个工作并保存它。那是外地工作的孩子。
如何将内部作业进度信息传递到外部作业状态检查?我在这里的代码似乎没有用。 (是的,我知道民意调查并不理想,但我不确定是否有更好的方法。)
答案 0 :(得分:1)
最终,我确实必须使用Write-Progress
- 最终代码(我并不为此感到骄傲)看起来像这样:
$child = Convert-VHD -Path $VHDPath -DestinationPath $NewVHDPath -ComputerName $TargetServer -VHDType Dynamic -ErrorAction 'SilentlyContinue' -AsJob
$child.Name = "... primary conversion work for $VHDPath"
Write-Progress -PercentComplete $child.Progress[-1].PercentComplete -Activity $child.ChildJobs[0].Progress[-1].Activity -Status $child.Progress[-1].StatusDescription
while ($child.State -eq 'NotStarted') {
Start-Sleep -Seconds 5
}
while ($child.State -eq 'Running') {
Write-Progress -PercentComplete $child.Progress[-1].PercentComplete -Activity $child.Progress[-1].Activity -Status $child.Progress[-1].StatusDescription
Start-Sleep -Seconds 5
}
Write-Progress -PercentComplete $child.Progress[-1].PercentComplete -Activity $child.ChildJobs[0].Progress[-1].Activity -Status $child.Progress[-1].StatusDescription
状态检查代码现在如下所示:
function Add-ProgressToList {
param (
[object] $actingJob
)
$displayTitle = $actingJob.Name
$JobID = $actingJob.Id
$JobState = $actingJob.JobStateInfo
$JobProgress = $actingJob.Progress[-1]
$JobPercent = $JobProgress.PercentComplete
$JobActivity = $JobProgress.Activity
$JobStatusDescription = $JobProgress.StatusDescription
if ($JobPercent -eq $null) {
$lstJobStatus.Items.Add("$JobID`: $displayTitle is $JobState")
} else {
$lstJobStatus.Items.Add("$JobID`: $displayTitle is $JobState ($JobActivity : $JobStatusDescription), $JobPercent%")
}
foreach ($Child in $actingJob.ChildJobs) {
Add-ProgressToList $Child
}
}
function Update-JobList {
Set-Cursor -Busy -Operation 'Updating job list...'
Clear-Listbox $lstJobStatus
Get-Job | foreach {
Add-ProgressToList $_
}
$lstJobStatus.SelectedIndex = $lstJobStatus.Items.Count - 1
$lstJobStatus.SelectedIndex = -1
Set-Cursor -Normal
$stsJobs.Text = Get-TabLastUpdateText
}
我停止了一份工作清单,因为我意识到我可以用描述性的方式使用工作名称。递归可以提升孩子的工作情况(实际上并没有发生这么多)。