• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 750
  • Last Modified:

How To Update GUI From Another PowerShell Job

So, I have a form. I want a button click to do something without locking up the form. I've done this in C#: I create a background worker and use the BeginInvoke method to update GUI elements and be thread safe. How do I do it in PowerShell? Here is what I've got so far:

$mainform = New-Object System.Windows.Forms.Form
$mainform.Text = "Test Form"
$mainform.Size = New-Object System.Drawing.Size(500,500)
$mainform.StartPosition = "CenterScreen"
$mainform.AutoSize = $false
$mainform.MinimizeBox = $false
$mainform.MaximizeBox = $false
$mainform.SizeGripStyle = "Hide"
$mainform.WindowState = "Normal"
$mainform.FormBorderStyle = "Fixed3D"
$mainfont = New-Object System.Drawing.Font("Arial",12)
$mainform.Font = $font

$statustxtbx = New-Object System.Windows.Forms.TextBox
$statustxtbx.Size = New-Object System.Drawing.Size(400,300)
$statustxtbx.Top = 60
$statustxtbx.Name = "StatusTextBox"
$statustxtbx.Multiline = $true
$statustxtbx.ScrollBars = "Vertical"
$statustxtbx.WordWrap = $true
$mainform.Controls.Add($statustxtbx)

$addbtn = New-Object System.Windows.Forms.Button
$addbtn.Size = New-Object System.Drawing.Size(80,30)
$addbtn.Text = "Add"
$addbtn.Add_Click({
    Start-Job -Name AddClick -ScriptBlock {
        [System.Windows.Forms.Messagebox]::Show("Hi")
        $statustxtbx.BeginInvoke({$statustxtbx.Text = "Disabling controls..."})
        for ($i = 0;$i -lt $mainform.Controls.Count; $i++) {
            $c = $mainform.Controls[$i]
            if ($c.Name -notlike "StatusTextBox") {
                $c.BeginInvoke({$c.Enabled = $false})
            }
        }
        $statustxtbx.BeginInvoke({$statustxtbx.Text += "done.`r`n`r`nSleeping for 10 seconds..."})
        sleep -Seconds 10
        $mainform.BeginInvoke({$statustxtbx.Text += "done.`r`nEnabling controls..."})
        for ($i = 0;$i -lt $mainform.Controls.Count; $i++) {
            $c = $mainform.Controls[$i]
            if ($c.Name -notlike "StatusTextBox") {
                $mainform.BeginInvoke({$c.Enabled = $true})
            }
        }
        $statustxtbx.BeginInvoke({$statustxtbx.Text += "done."})
    }
    #$statustxtbx.Text += "Some Text `r`n"
})
$mainform.Controls.Add($addbtn)
$mainform.Add_Shown({$mainform.Activate()})
$mainform.ShowDialog()

Open in new window

0
byt3
Asked:
byt3
  • 2
1 Solution
 
Joe KlimisCommented:
Hi
You have used start-job, when  I think you need to be using runspaces which will allow you to share  varialbles between processes

An example of this can be found here  , http://learn-powershell.net/2013/04/19/sharing-variables-and-live-objects-between-powershell-runspaces/sharing-variables-and-live-objects-between-powershell-runspaces

if you detail you exact requirements i will try and help you
0
 
byt3Author Commented:
Thanks for the link. I will check it out and see how to use runspaces.

Ultimately this is a tool that a client will use to create public folders and mail enable them. That part I don't need assistance on. What I need help with is after the button is clicked and the public folder stuff is happening I need to the form to not lock up by using a background process somehow. During the process I want to update the text in the textbox as an output of what the tool is currently doing.
0
 
byt3Author Commented:
Runscpaces is exactly what I needed. I also need to change the code for invoking the control as well:

BeginInvoke( { <code> } )

Open in new window


To

BeginInvoke( [action]{ <code } )

Open in new window

0

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now