我正在处理的脚本的一部分使用指定的用户名,在名为username的计算机上搜索活动目录,ping它们,然后将在线计算机添加到阵列以供稍后使用。我想在脚本的ping部分添加一个进度条,但我遇到了问题。如果我在ping循环之前调用它,我必须提供进度条的表单冻结脚本的执行。
以下是进度条的代码(非常基本):
#Progress Bar
$objFormPBar = New-Object System.Windows.Forms.Form
$objFormPBar.Text = "Loading"
$objFormPBar.Size = New-Object System.Drawing.Size(200,100)
$objFormPBar.StartPosition = "CenterScreen"
$objFormPBar.Topmost = $True
$objFormPBar.Icon = $Icon
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Size = New-Object System.Drawing.Size(175,20)
$progressBar.Location = New-Object System.Drawing.Size(5, 20)
$progressBar.Minimum = 0
$progressBar.Maximum = 0
$objFormPBar.Controls.Add($progressBar)
这是我试图显示它的地方,这样就停止了脚本的执行(从点击处理函数内部调用,因此全局变量):
$global:progressBar.Maximum = $computers.count
$global:objFormPBar.Add_Shown({$objFormPBar.Activate()})
[void] $global:objFormPBar.ShowDialog()
Foreach ($computer in $computers) {
$computer = $computer.trim()
If(Test-Connection $computer -Count 1) {
$arrayComputers.add($computer) | Out-Null
}
$global:progressBar.Increment(1)
}
$global:objFormPBar.Close()
调查问题我发现你可以在一个单独的线程中运行进度条并在两者之间传递变量(参见:Marquee Progress Bar freezes in Powershell)。但是,我没有运气让它工作,甚至没有让另一个线程启动。如何获得此进度条和表单以及在另一个线程中运行?
答案 0 :(得分:0)
为什么不直接使用内置UI报告PowerShell中的进度?这是对Write-Progress
的单行调用,例如:
$computers = 1..10 | % {"server$_"}
$numComputers = $computers.Length
for ($ndx = 0; $ndx -le $numComputers; $ndx++) {
$computer = $computers[$ndx].Trim()
Write-Progress "Testing connection to $computer" -PercentComplete ($ndx/$numComputers * 100)
#if (Test-Connection $computer -Count 1) {
# $arrayComputers.add($computer) | Out-Null
#}
Start-Sleep -Seconds 1
}
BTW上述方法的主要问题是在窗体关闭之前,ShowDialog()
方法调用不会返回。如果要使用ShowDialog(),则必须在表单内的事件处理程序(Load / Activate)的上下文中执行逻辑。另一种选择是使用Show()
,但这意味着您必须使用Application.DoEvents()在循环中抽取消息,以便表单有机会自行更新。