If I run the following code, the Event Action is executed:
$Job = Start-Job {\'abc\'}
Register-ObjectEvent -InputObject $Job -EventName StateChanged `
-
The state property of Powershell jobs is read-only; this means that you can't configure the job state to be anything before you actually start the job. When you're monitoring for the statechanged event, it doesn't fire until the click event comes around again and the state is 'seen' to change from 'running' to 'completed' at which point your script block executes. This is also the reason why the scriptblock executes when closing the form.
The following script removes the need to monitor the event and instead monitors the state. I assume you want to fire the on 'statechanged' code when the state is 'running'.
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$Form1 = New-Object Windows.Forms.Form
$Form1.Add_Shown({
$Form1.Activate()
})
$Button1 = New-Object System.Windows.Forms.Button
$Button1.Text = 'Test'
$Form1.Controls.Add($Button1)
$Button1.Add_Click({
$this.Enabled = $false
Write-Host $Job.State " - (Before job started)"
$Job = Start-Job {'abc'}
Write-Host $Job.State " - (After job started)"
If ($Job.State -eq 'Running') {
Start-Sleep -Seconds 1
Write-Host '*Doing Stuff*'
}
Write-Host $Job.State " - (After IF scriptblock finished)"
[System.Windows.Forms.Application]::DoEvents()
$this.Enabled = $true
})
$Form1.ShowDialog()
In addition, note the lines:
$this.Enabled = $false
[System.Windows.Forms.Application]::DoEvents()
$this.Enabled = $true
These lines ensure the button doesn't queue click events. You can obviously remove the 'write-host' lines, I've left those in so you can see how the state changes as the script executes.
Hope this helps.