Change InvokeRequired to True

Ask questions about creating Graphical User Interfaces (GUI) in PowerShell and using WinForms controls.
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
This topic is 4 years and 4 months old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked
User avatar
Bender2010
Posts: 6
Last visit: Mon Jan 29, 2024 1:29 am

Change InvokeRequired to True

Post by Bender2010 »

Hello,

I have a GUI with a label which is not visible ($false). I would like to visible the item with BeginInvoke(). So long the task is running, the item is visible and when finished not.

When I have understand, then I must change InvokeRequired to True, so I could change objects outsite my task.
https://docs.microsoft.com/en-us/dotnet ... keRequired

How I could change this settings for my label and other items? When I do this in my script ($label.InvokeRequired = $true), it´s not working while it´s a read only property.

PowerShell Studio 2019. 5.6.170
64 Bit

Best thanks for your assitent

Code: Select all

	# Runspace 
	$runspaceSpace = [RunspaceFactory]::CreateRunspace()
	$runspaceSpace.ApartmentState = 'STA'
	$runspaceSpace.ThreadOptions = 'UseNewThread'
	$runspaceSpace.Open()
	
	# PSInstance
	$PsInstanceSpace = [PowerShell]::Create()
	$PsInstanceSpace.Runspace = $runspace
	
	# Space
	$PsInstanceSpace.Runspace.SessionStateProxy.SetVariable("labelSpaceStatus", $labelSpaceStatus)
	$PsInstanceSpace.Runspace.SessionStateProxy.SetVariable("labelSpaceOK", $labelSpaceOK)
	$PsInstanceSpace.Runspace.SessionStateProxy.SetVariable("labelSpaceX", $labelSpaceX)
	$PsInstanceSpace.Runspace.SessionStateProxy.SetVariable("progressbarSpace", $progressbarSpace)
	
	#$labelSpaceOK.InvokeRequired = $true
	#$labelSpaceX.InvokeRequired = $true
	
	[void]$PsInstanceSpace.AddScript({
			#Place Code Here
			If ((Get-WMIObject -Class Win32_Logicaldisk -Namespace Root\CIMV2 -Filter "deviceid='C:'").FreeSpace -gt 31457280000)
			{
				$labelSpaceStatus.Text = "Success"
				$labelSpaceOK.Visible = $true #Show my label now
				$labelSpaceX.Visible = $false
			}
			else
			{
				$labelSpaceStatus.Text = "Failed"
				$labelSpaceOK.Visible = $false
				$labelSpaceX.Visible = $true
			}
			[System.Windows.Forms.MessageBox]::Show("Script is running", "Running")
			$progressbarSpace.Visible = $false
			$PsInstanceSpace.EndInvoke()
			$PsInstanceSpace.Dispose()
			$runspaceSpace.Close()
			[System.GC]::Collect()
		}).BeginInvoke()
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Change InvokeRequired to True

Post by jvierra »

Invoke is not required to change properties. It is only required for calling delegates. Just set the property. The synchash will handle threading issues.

You must use a synchash and not just assigned variables.
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Change InvokeRequired to True

Post by jvierra »

Here is the way to create a basic invokable script that builds and manages the runspace for you with correct default values and a synchash.

Since the "Visible" property is not really a simple property you would have tocreate a delegate that can calll the "Show()" method on the control. I can't remember the syntax for that in PowerShell right now.

The "InvokeRequired" is not needed here and is not a settable property. It is used so a thread can decide whether to directly access a control or if an "Invoke" is required.

See attached demo for how to code this.
Attachments
Demo-SimpleRunspace.psf
(31.69 KiB) Downloaded 86 times
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Change InvokeRequired to True

Post by jvierra »

Ok. I remembered the trick with PS. Here is how to call a delegate from a runspace and set the visible property to true.

Code: Select all

$buttonStart_Click={
    $synchash = @{
        Label = $label1
        Show = [action]{$label1.Visible = $true}
    }
    $psscript = {
        $synchash.Label.Invoke($synchash.Show)
        1..100 |
            ForEach-Object{
                $synchash.Label.Text = "$_ Runspace here"
                sleep 1
            }
    }
    
    # create a new PowerShell runspace
    $ps = [PowerShell]::Create()
    $ps.Runspace.SessionStateProxy.SetVariable('synchash',$synchash)
    $ps.AddScript($psscript)
    $ps.BeginInvoke()
}
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Change InvokeRequired to True

Post by jvierra »

Here is a full example of how to manage a runspace including how to detect when it is complete and how to detect errors.
Attachments
Demo-SimpleRunspace2.psf
(32.72 KiB) Downloaded 86 times
This topic is 4 years and 4 months old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked