Powershell:While冻结表格

时间:2020-05-12 18:50:31

标签: forms powershell loops while-loop freeze

我正在尝试制作一个带有复选框的软件。应该执行以下操作

  • 如果已选中复选框:
  • 检查“记事本”是否正在运行
  • 如果没有,请启动“记事本”
  • 等待约5秒钟,然后重复

代码按预期执行,但也会冻结Windows窗体。我想避免这种情况。 我尝试添加 [System.Windows.Forms.Application] :: DoEvents()

在8和9行之间,但无济于事

原始代码

$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
        }
    }

完整的ps1文件代码如下:

#------------------------------------------------------------------------
# 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

1 个答案:

答案 0 :(得分:2)

您不应该从复选框事件处理程序内部运行while循环。

您的表单一旦检查是否选中了该复选框,它将冻结表单,因为它位于单个线程中,并且该线程陷入了while循环中。

仅当您希望某项在复选框更改状态时运行一次时,才应真正使用CheckedChanged处理程序。

要基于复选框的状态连续运行的功能可以使用计时器来完成。

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

您可以这样设置一个计时器:

$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
}

然后使用复选框启用和禁用它:

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