Home > Back-end >  Progress bar with a timer in PowerShell
Progress bar with a timer in PowerShell

Time:10-22

I'm trying to create a progress bar in PowerShell, I would like the progress bar to reach 100% after certain amount of time. The below script does that but I have to click on the button to get it started. Is there way to start the progress bar right away without the need to click on the button? FYI: I'm simply trying to create a progress bar that will reach 100% after set amount of time. Below is my script:

Function StartProgressBar
{
    if($i -le 5){
        $pbrTest.Value = $i
        $script:i  = 1
    }
    else {
        $timer.enabled = $false
    }   
}

$Form = New-Object System.Windows.Forms.Form
$Form.width = 400
$Form.height = 200
$Form.Text = "Add Resource"

# Init ProgressBar
$pbrTest = New-Object System.Windows.Forms.ProgressBar
$pbrTest.Maximum = 100
$pbrTest.Minimum = 0
$pbrTest.Location = new-object System.Drawing.Size(10,10)
$pbrTest.size = new-object System.Drawing.Size(100,50)
$i = 0
$Form.Controls.Add($pbrTest)

# Button
$btnConfirm = new-object System.Windows.Forms.Button
$btnConfirm.Location = new-object System.Drawing.Size(120,10)
$btnConfirm.Size = new-object System.Drawing.Size(100,30)
$btnConfirm.Text = "Start Progress"
$Form.Controls.Add($btnConfirm)

$timer = New-Object System.Windows.Forms.Timer 
$timer.Interval = 1000

$timer.add_Tick({
StartProgressBar
})

$timer.Enabled = $true
$timer.Start()

# Button Click Event to Run ProgressBar
$btnConfirm.Add_Click({
    
    While ($i -le 100) {
        $pbrTest.Value = $i
        Start-Sleep -m 1
        "VALLUE EQ"
        $i
        $i  = 1
    }
})

# Show Form
$Form.Add_Shown({$Form.Activate()})
$Form.ShowDialog() ```  

CodePudding user response:

I think if you remove the onclick event it will run automatically but I don't know if this is obvious.

Function StartProgressBar
{
    if($i -le 5){
        $pbrTest.Value = $i
        $script:i  = 1
    }
    else {
        $timer.enabled = $false
    }   
}

$Form = New-Object System.Windows.Forms.Form
$Form.width = 400
$Form.height = 200
$Form.Text = "Add Resource"

# Init ProgressBar
$pbrTest = New-Object System.Windows.Forms.ProgressBar
$pbrTest.Maximum = 100
$pbrTest.Minimum = 0
$pbrTest.Location = new-object System.Drawing.Size(10,10)
$pbrTest.size = new-object System.Drawing.Size(100,50)
$i = 0
$Form.Controls.Add($pbrTest)

# Button
$btnConfirm = new-object System.Windows.Forms.Button
$btnConfirm.Location = new-object System.Drawing.Size(120,10)
$btnConfirm.Size = new-object System.Drawing.Size(100,30)
$btnConfirm.Text = "Start Progress"
$Form.Controls.Add($btnConfirm)

$timer = New-Object System.Windows.Forms.Timer 
$timer.Interval = 1000

$timer.add_Tick({
StartProgressBar
})

$timer.Enabled = $true
$timer.Start()

# Button Click Event to Run ProgressBar
While ($i -le 100) {
    $pbrTest.Value = $i
    Start-Sleep -m 1
    "VALLUE EQ"
    $i
    $i  = 1
}

# Show Form
$Form.Add_Shown({$Form.Activate()})
$Form.ShowDialog()

CodePudding user response:

I made some adjustments to your code.

  • I have renamed your function StartProgressBar into Update-ProgressBar because it will be called upon on every timer tick to update the statusbar, so the name is more self explanatory I think
  • the button now is only there to re-start the progressbar if needed.
  • you don't need counter $i because the ProgressBar object itself has all properties you need to keep track of its current value. Also, if you do want a counter, inside the function (and other scriptblocks) you need to address it with $script:i. Without that script-scope, $i does not exist there.
  • to have the progressbar start running on startup, you need to enable and start the timer using $Form.Add_Shown({$timer.Enabled = $true; $timer.Start()})
  • to show the form on top of other windows, set $Form.Topmost = $true

Here's the code:

function Update-ProgressBar {
    # this function will be called on every timer tick
    $pbrTest.PerformStep()
    $progressLabel.Text = "VALUE EQ $($pbrTest.Value)%"
    
    if ($pbrTest.Value -ge $pbrTest.Maximum) {
        $timer.Enabled = $false
        $timer.Stop()
        $btnRestart.Enabled = $true
    }
}

$Form = New-Object System.Windows.Forms.Form
$Form.Width = 400
$Form.Height = 200
$Form.Text = "Add Resource"
$Form.Topmost = $true  # place this form on top

# Init ProgressBar
$pbrTest = New-Object System.Windows.Forms.ProgressBar
$pbrTest.Location = New-Object System.Drawing.Point(10,10)
$pbrTest.Size = New-Object System.Drawing.Size(100,50)
$pbrTest.Maximum = 100
$pbrTest.Minimum = 0
$pbrTest.Value = 0
$pbrTest.Step = 1
$Form.Controls.Add($pbrTest)

# Button
$btnRestart = New-Object System.Windows.Forms.Button
$btnRestart.Location = New-Object System.Drawing.Size(120,10)
$btnRestart.Size = New-Object System.Drawing.Size(100,30)
$btnRestart.Text = "Restart Progress"
$btnRestart.Enabled = $false  # disabled at first
$btnRestart.Add_Click({ 
    # disable this button while the progressbar is running
    $this.Enabled = $false  
    # reset the progressbar to value 0 and start the timer
    $pbrTest.Value = 0
    $timer.Enabled = $true
    $timer.Start()
})
$Form.Controls.Add($btnRestart)

# Label
$progressLabel = New-Object System.Windows.Forms.Label
$progressLabel.Size = '370, 20'
$progressLabel.Location = '10,70'
$progressLabel.Text = "Processing..."
$Form.Controls.Add($progressLabel)

# Timer
$timer = New-Object System.Windows.Forms.Timer 
$timer.Interval = 50
$timer.Enabled = $false  # disabled at first
$timer.Add_Tick({ Update-ProgressBar })

# start the timer as soon as the form is shown
$Form.Add_Shown({$timer.Enabled = $true; $timer.Start()})

# Show Form
$Form.ShowDialog()

# stop the timer and dispose of it and finally also dispose of the form
$timer.Stop()
$timer.Dispose()
$pbrTest.Dispose()
$Form.Dispose()
  • Related