Powershell显示弹出窗口并在循环时不断更新弹出窗口的主体

Powershell display pop-up and keep update the body of pop-up while loop

我正在尝试制作弹出窗口,其中包含正文中的一些数据,以便使用 powershell 显示。
虽然,我测试了一些方法来正确地做到这一点。但是我找不到任何方法来在更新弹出消息时保持循环进度。

请检查下面的消息框。

虽然,我不明白为什么 png 文件没有正确上传..
所以我在下面添加了我的 powershell 代码。

PowerShell 代码如下。

$msgBoxTitle = "i value"
$i = 0
while(1){
    $msgBoxBody = "
        current i value is : $i
    "
    $i++;
    [System.Windows.MessageBox]::Show($msgBoxBody, $msgBoxTitle)
}

在这种情况下,我想让循环在循环进行时不停止,并且消息框正文的值得到更新。

有没有办法做到这一点? 谢谢。

这不是微不足道的,因为(简单地说)PowerShell 不能很好地处理表单。 This anwer 解释了 为什么 并给出了如何显示 non-blocking 表单或消息框的解决方案:

$ps = [PowerShell]::Create()
[void]$ps.AddScript({
    param($Caption, $Text)
    Add-Type -AssemblyName System.Windows.Forms
    [System.Windows.Forms.MessageBox]::Show($Text, $Caption)
})
[void]$ps.AddArgument($msgBoxTitle)
[void]$ps.AddArgument($msgBoxBody)
[void]$ps.BeginInvoke()

但是... 更新 表格会很棘手,我不确定是否有简单的方法可以做到.

This answer mentions showui,一个 PowerShell 模块,但我对此一无所知,对于你的问题来说它可能有点过分了。

在 PowerShell 中显示进度的最佳实践Write-Progress。对您的代码进行一点更新:

$msgBoxTitle = "i value"
$i = 0
while (1) {
    $msgBoxBody = "current i value is : $i"
    $i++;
    Write-Progress -Activity $msgBoxTitle -Status $msgBoxBody
}

(当然,当您知道操作需要多长时间并且您可以指定一个百分比时,Write-Progress 效果最好,因此它会显示一个进度条。但如您所见,它甚至可以在没有那个。)

您可以创建自己的弹出表单,而不是使用 ShowDialog() 方法,只使用 Show()。 然后在脚本的其余部分更新标签并在完成后处理它。

为方便起见,我将创建示例表单的代码放在函数中

function Show-MyPopup {
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing

    $form = New-Object System.Windows.Forms.Form
    $form.Size = New-Object System.Drawing.Size(400,200)
    $form.FormBorderStyle = 'FixedSingle'
    $form.StartPosition = 'CenterScreen'
    $form.TopMost = $true
    $form.ControlBox = $False
    $form.Text = 'i value'

    $label = New-Object System.Windows.Forms.Label
    $label.Size = New-Object System.Drawing.Size(360,22)  # or write '360,22'
    $label.Left = ($form.Width - $label.Width) / 2
    $label.Top = ($form.Height - $label.Height * 2) / 2
    $label.Text = 'Current i value is: 0'
    # in order to address this control later, you must Name it
    $label.Name = 'Label1'
    $form.Controls.Add($label)

    $button = New-Object System.Windows.Forms.Button 
    $button.Size = New-Object System.Drawing.Size(75,24)
    $button.Left = $form.Width - $button.Width - 20
    $button.Top = $form.Height - $button.Height * 3
    $button.Text = 'Exit'
    $button.Add_Click({ $form.Close() })
    $form.Controls.Add($button)
    $form.AcceptButton = $button
    $form.Show()
    # return the form object to the calling script
    $form
}

有了它,在它下面写下控制表单的脚本的其余部分:

# call the function to show the popup and capture the form itself in a variable
$popup = Show-MyPopup
for ($i = 1; $i -le 10; $i++) {
    # update the label using the form's Controls collection
    $popup.Controls.Item('Label1').Text = "Current i value is: $i"
    # do what needs to be done here.
    # for demo, just sleep for one second
    Start-Sleep -Seconds 1
}

# very important! remove the form from memory when done
$popup.Dispose()
$popup = $null