Form with runspace

Welcome Forums General PowerShell Q&A Form with runspace

This topic contains 2 replies, has 2 voices, and was last updated by

 
Participant
1 week, 5 days ago.

  • Author
    Posts
  • #127992

    Participant
    Points: 35
    Rank: Member

    I have the below code in a simple form, the bit I am not having any luck with I want the form to close when the countdown has reached 1. I am not sure what event I need to trigger (or where to put it) as the counter is running in a runspace.

    [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
    Add-Type -AssemblyName System.Windows.Forms
    
    $sync = [Hashtable]::Synchronized(@{})
    
    # Countdown Timer
    $counter = {
    $count = [PowerShell]::Create().AddScript({
    for ($i = 5; $i -gt 0; $i--) {
    $sync.label.Text = $i
    start-sleep -seconds 1
    if($i -eq 1) {$form.close()}
    }
    
    })
    
    $runspace = [RunspaceFactory]::CreateRunspace()
    $runspace.ApartmentState = "STA"
    $runspace.ThreadOptions = "ReuseThread"
    $runspace.Open()
    $runspace.SessionStateProxy.SetVariable("sync", $sync)
    
    $count.Runspace = $runspace
    $count.BeginInvoke()
    
    }
    
    # create the form.
    $form = New-Object Windows.Forms.Form
    $form.ClientSize = New-Object Drawing.Size(200, 60)
    $form.Text = "Counter"
    $form.StartPosition = "CenterScreen"
    $form.FormBorderStyle = "FixedSingle"
    $form.MaximizeBox = $false
    
    # create the button.
    $button = New-Object Windows.Forms.Button
    $button.Location = New-Object Drawing.Point(10, 10)
    $button.Width = 180
    $button.Text = "Close"
    $button.Add_Click({$form.close()})
    
    # create the label.
    $label = New-Object Windows.Forms.Label
    $label.Location = New-Object Drawing.Point(10, 38)
    $label.Width = 100
    $label.Text = 0
    $form.add_Load($counter)
    # add controls to the form.
    $sync.button = $button
    $sync.label = $label
    $form.Controls.AddRange(@($sync.button, $sync.label))
    
    # show the form.
    [Windows.Forms.Application]::Run($form)
    
    
  • #128025

    Participant
    Points: 105
    Helping Hand
    Rank: Participant

    It looks like a job for System.Windows.Forms.Timer. It runs in the same thread, and is thus thread-safe...

    [int]$countValue = 5
    
    $timer= New-Object Windows.Forms.Timer
    $timer.Interval = 1000 # trigger interval in milliseconds
    $timer.Add_Tick({
        $script:countValue--
        $label.Text = $countValue
        if($countValue -eq 0) {
            $timer.Stop()
            $form.Close()
        }
    })
    
    $form.Add_Load({
        $label.Text = $countValue
        $timer.Start()
    })
    
  • #128176

    Participant
    Points: 35
    Rank: Member

    Thanks for your input. I ended up using the timer as ran out of time to deliver the solution. I may revisit at some point to get a run space solution working as we have several forms that use this technology.

You must be logged in to reply to this topic.