I have a list of statuses that will need to be checked every 5 seconds, then update a panel in my gui. With my current code, I have a Timeout set to an hour and a while loop that will run the Show-Statuses function which updates the GUI.

My issue is that when this While loop is entered, the Form.ShowDialog() will never bet triggered.

How do I make it so I can show the form and the continuously update a portion of it?

Function Determine-JabadStatus {

    $JabadLOStatus = (Get-Aduser adepolo -Properties LockedOut).LockedOut

    If ($JabadLOStatus -eq $False) {
        $JabadStatusF = "Unlocked"
    } else {
        $JabadStatusF = "Locked"
    }

    $JabadStatusF
}

Function Show-Statuses {

    #Load statuses
    $JabadStatus = Determine-JabadStatus

    #Add each status seperated by + "`r`n`r`n" + quotes
    $ImportantInformationStatuses.Text = $JabadStatus 
}

$Timeout = New-TimeSpan -Hours 1
$sw = [diagnostics.stopwatch]::StartNew()

While ($sw.Elapsed -lt $Timeout) {
    Show-Statuses
    Start-Sleep -Seconds 5
}

$form.ShowDialog()

2 Answers

2
Drew On

Assuming your $ImportantInformationStatuses is a label or something similar, then a .Refresh() should work.

Function Show-Statuses{
    #Load statuses
    $JabadStatus = Determine-JabadStatus

    #Add each status seperated by + "`r`n`r`n" + quotes
    $ImportantInformationStatuses.Text = $JabadStatus 
    $ImportantInformationStatuses.Refresh()
}

I would recommend looking into jobs though using the windows forms timer to trigger your loop, something like this.

$JobScript = {
    If((get-aduser adepolo -Properties LockedOut).LockedOut) {
        $JabadStatusF = "Locked"
    } Else {
        $JabadStatusF = "Unlocked"
    }
    Return $JabadStatusF
}


Function JobLoop {
    $Job = Start-Job -ScriptBlock $JobScript
    $Status = (Receive-job $job -Wait)
    $ImportantInformationStatuses.Text = $Status
}

$Timer = New-Object System.Windows.Forms.Timer
$Timer.Interval = 5000
$Timer.add_tick({JobLoop})
$Timer.Start() # Do $Timer.Stop() & $Timer.Dispose() to stop the loop.
0
Graham Jordan On

Try putting this into your While

 $form.Dispatcher.Invoke( [Action]{},[Windows.Threading.DispatcherPriority]::ContextIdle )

i.e.

While ($sw.Elapsed -lt $Timeout) {
    Show-Statuses
    $form.Dispatcher.Invoke( [Action]{},[Windows.Threading.DispatcherPriority]::ContextIdle )
    Start-Sleep -Seconds 5
}

I use that line of text when updating progress bars within a GUI, and when dumping output into a RichTextbox. It should work for you too.