Jonas Roland
Jonas Roland

Reputation: 45

Powershell: While loop freezing form

I'm attempting to make a piece of software with a checkbox. It is supposed to do the following

The code does as intended but it also freezes the windows form. I would like to avoid this. I have tried adding [System.Windows.Forms.Application]::DoEvents()

Between line 8 & 9 but to no avail

Raw code:

$form1_Load={   
}

$checkbox1_CheckedChanged={

        # While checkbox is checked, if proces is not running, launch it. Check every 5 seconds.
        while ($checkbox1.Checked = $true)
        {
            Set-Location -path "C:\Windows\System32"
            If (!(Get-Process -Name notepad -ErrorAction SilentlyContinue))
            {
                ./notepad.exe |
                Exit-PSSession
            }
            sleep 5
        }
    }

The full ps1 file code is as follows:

#------------------------------------------------------------------------
# Source File Information (DO NOT MODIFY)
# Source ID: 9f18f45d-8ced-4efb-9f9a-ab7fafc2d9ec
# Source File: C:\Users\Jonas\Documents\SAPIEN\PowerShell Studio\Projects\test22\MainForm.psf
#------------------------------------------------------------------------
#region File Recovery Data (DO NOT MODIFY)
<#RecoveryData:
uwIAAB+LCAAAAAAABABlkkuPolAUhPck/AfT204akJckjglvBAXxAgI7UOQiCMgbfn3bPZtJ5qwq
p1KLqnzbc3KthqSZpaiLVm/RZlX554P8Ij52KLJaba0mS7MyKpSsSMzomeyOUVYqVfP8qtv7FvvP
/g39+Dvb0D3ifqRj2+Z50ZJE/u8JvEh4CnEaH7x7d+7TaTlz/lN6APwRyPUTqIqq7yUGNE0n1pdO
J+ZyIbiuq8RHhiJ0ZYZ4A2iam5Z1aS1YQY6S4mhkn+v2QGapBhgB3k54ASVP6/J9DYbrBa88D7TK
8KpDQw5fOtSpOHyhyG0Iw1n+pBwIKB4anXi42xafUxWX2E7vGlDor2Uor2M/ufrNUbk1iZYD8ez6
1Iyd5yOjHyZXyK/cy7dRBAz7gF4iE49VEBE8Q54PljzjZaGJVCCo+2UPhFu25OZpILQYHJPMlEaT
/Rlqfg/FM3zBHqmz2q0vEEXO7bXWb+tI8QeacF+Tyz2qZd8b0kv1D3jIZlOny0+aXRqTG2jav3HS
bL1746bHxwPFuXWlC/5hiZhZQxFpUUGhwgev9VxTlU4M583EqhoGxXYUM3Czxnb2AgXTbdmbDVm6
x63Rp5vlgFFJ8BAKTotIaUlzUxtQZLymtQ7j4MlU8qu5BK2TwruhO1Jqih7L5i4kS5bivBN07c+8
zRQo9UnIYY0/xh1ZTfHmMtAna1xv4gRFLGYqUjB1wpuOLfYLzy9GfNsmz7jIknaFvT9b7F9Yd989
jPyZuwIAAA==#>
#endregion

<#
    .NOTES
    --------------------------------------------------------------------------------
     Code generated by:  SAPIEN Technologies, Inc., PowerShell Studio 2020 v5.7.172
     Generated on:       12/05/2020 20.25
     Generated by:       Jonas
    --------------------------------------------------------------------------------
    .DESCRIPTION
        GUI script generated by PowerShell Studio 2020
#>


#----------------------------------------------
# Generated Form Function
#----------------------------------------------
function Show-MainForm_psf {

    #----------------------------------------------
    #region Import the Assemblies
    #----------------------------------------------
    [void][reflection.assembly]::Load('System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
    [void][reflection.assembly]::Load('System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089')
    #endregion Import Assemblies

    #----------------------------------------------
    #region Generated Form Objects
    #----------------------------------------------
    [System.Windows.Forms.Application]::EnableVisualStyles()
    $form1 = New-Object 'System.Windows.Forms.Form'
    $checkbox1 = New-Object 'System.Windows.Forms.CheckBox'
    $InitialFormWindowState = New-Object 'System.Windows.Forms.FormWindowState'
    #endregion Generated Form Objects

    #----------------------------------------------
    # User Generated Script
    #----------------------------------------------
    $form1_Load={   
    }

    $checkbox1_CheckedChanged={


            # While checkbox is checked, if proces is not running, launch it. Check every 5 seconds.
            while ($checkbox1.Checked = $true)
            {
                Set-Location -path "C:\Windows\System32"
                If (!(Get-Process -Name notepad -ErrorAction SilentlyContinue))
                {
                    ./notepad.exe |
                    Exit-PSSession
                }
                sleep 5
            }
        }


    # --End User Generated Script--
    #----------------------------------------------
    #region Generated Events
    #----------------------------------------------

    $Form_StateCorrection_Load=
    {
        #Correct the initial state of the form to prevent the .Net maximized form issue
        $form1.WindowState = $InitialFormWindowState
    }

    $Form_Cleanup_FormClosed=
    {
        #Remove all event handlers from the controls
        try
        {
            $checkbox1.remove_CheckedChanged($checkbox1_CheckedChanged)
            $form1.remove_Load($form1_Load)
            $form1.remove_Load($Form_StateCorrection_Load)
            $form1.remove_FormClosed($Form_Cleanup_FormClosed)
        }
        catch { Out-Null <# Prevent PSScriptAnalyzer warning #> }
    }
    #endregion Generated Events

    #----------------------------------------------
    #region Generated Form Code
    #----------------------------------------------
    $form1.SuspendLayout()
    #
    # form1
    #
    $form1.Controls.Add($checkbox1)
    $form1.AutoScaleDimensions = '6, 13'
    $form1.AutoScaleMode = 'Font'
    $form1.ClientSize = '284, 261'
    $form1.Name = 'form1'
    $form1.Text = 'Form'
    $form1.add_Load($form1_Load)
    #
    # checkbox1
    #
    $checkbox1.Location = '98, 102'
    $checkbox1.Name = 'checkbox1'
    $checkbox1.Size = '104, 24'
    $checkbox1.TabIndex = 0
    $checkbox1.Text = 'checkbox1'
    $checkbox1.UseCompatibleTextRendering = $True
    $checkbox1.UseVisualStyleBackColor = $True
    $checkbox1.add_CheckedChanged($checkbox1_CheckedChanged)
    $form1.ResumeLayout()
    #endregion Generated Form Code

    #----------------------------------------------

    #Save the initial state of the form
    $InitialFormWindowState = $form1.WindowState
    #Init the OnLoad event to correct the initial state of the form
    $form1.add_Load($Form_StateCorrection_Load)
    #Clean up the control events
    $form1.add_FormClosed($Form_Cleanup_FormClosed)
    #Show the Form
    return $form1.ShowDialog()

} #End Function

#Call the form
Show-MainForm_psf | Out-Null

Upvotes: 3

Views: 1499

Answers (1)

retryW
retryW

Reputation: 693

You shouldn't be running a while loop from inside your checkbox event handler.

As soon as your form checks if the checkbox is checked, it'll freeze the form as it's on a single thread, and that thread is stuck in a while loop.

The CheckedChanged handler should only really be used if you want something to run once when the checkbox changes state.

Functionality you want to run continuously based on the state of the checkbox could be done using a timer.

https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.timer?redirectedfrom=MSDN&view=netcore-3.1

You could setup a timer like this:

$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 5000 # In milliseconds
$timer.add_tick({OpenNotePad()})

function OpenNotepad() {
    Set-Location -path "C:\Windows\System32"
    if (!(Get-Process -Name notepad -ErrorAction SilentlyContinue)) {
        ./notepad.exe
    }
}

function startTimer() { 
   $timer.start()
}

function stopTimer() {
    $timer.Enabled = $false
}

Then enable and disable it with the checkbox:

$checkbox1_CheckedChanged={
    if($checkbox1.checked) { # You could also check if timer is already running
        startTimer()
    } else {
        stopTimer()
    }
}

Upvotes: 3

Related Questions