2

I'm trying to make pop-up with some data in the body to display with powershell.
Although, I tested some method to make this correctly. But I couldn't find any way to keep loop progress while pop-up message is being updated.

Please check below message box.

powershell.png

Although, I don't understand why the png file is not correctly uploaded..
So I add my powershell code below.

And the PowerShell code is like below.

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

With this condition, I want to make the loop doesn't stop while loop is going on and the msg box body's value get updated.

Is there any possible way to make this? Thank you.

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
홍종우
  • 37
  • 4

2 Answers2

2

You could create your own popup form and instead of using the ShowDialog() method, have it only Show(). Then in the rest of the script you update the label and dispose of it when done.

For convenience, I've put the code to create a sample form in a function

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
}

With that in place, below it write the rest of the script that controls the 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
Theo
  • 57,719
  • 8
  • 24
  • 41
1

This is not trivial, because (simply put) PowerShell does not very work well with forms. This anwer explains why and gives a solution how to show a non-blocking form or message box:

$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()

However... updating the form would be tricky, and I am not sure if there is an easy way to do it.

This answer mentions showui, a PowerShell module, but I don't know anything about it, and it would be probably overkill for your problem.

The best practice to display progress in PowerShell is Write-Progress. A little update to your code:

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

(Of course, Write-Progress works best when you know how long the operation will take and you can specify a percentage, so it will display a progress bar. But as you can see, it even works without that.)

marsze
  • 15,079
  • 5
  • 45
  • 61