Powershell表单 - 使用按钮暂停循环

问题描述 投票:1回答:2

我有一个基于表单的脚本,可以从各种来源执行大量的文件副本。复制文件的主循环可以运行很长时间,我想添加一个暂停按钮来保持处理(直到再次按下暂停按钮)

遵循here的建议,我使用[System.Windows.Forms.Application]::DoEvents()来保持表单响应,并提供一种方法,如果需要优雅地打破复制循环。

我很难看到如何引入一个按钮来暂停“ForEach”循环而不是打破它 - 任何人都可以指出我正确的方向,因为我尝试使用Do-Until / While似乎以某种方式挂起脚本?

我正在做的一个非常简化的样本如下:

$StartCopyButton.Add_Click({
    $script:CancelLoop = $false
    $script:PauseToggle = $false
    $CancelButton.Enabled = $true
    $StartCopyButton.Enabled = $false

    Get-ChildItem -LiteralPath $Source -Recurse -File | ForEach {
        Copy-Item -Path $.FullName -Destination $NewDestination
        [System.Windows.Forms.Application]::DoEvents()
        If($script:CancelLoop -eq $true) {
            #Exit the loop
            Break;
        }
        If ($script:PauseToggle) {
            Do { 
            [System.Windows.Forms.Application]::DoEvents()
            } Until (!$script:PauseToggle)
        }
    }
    $CancelButton.Enabled = $false
    $StartCopyButton.Enabled = $true
})

$CancelButton.Add_Click({
    $script:CancelLoop = $true
})
$PauseButton.Add_Click({
    # Boolean change value to true/false
    $script:PauseToggle = !$script:PauseToggle
})
powershell
2个回答
1
投票

您可以检查Pause状态,如果是,则使用DoEvents进行空循环。像这样(虽然没有测试过):

$StartCopyButton.Add_Click({
    $script:CancelLoop = $false
    $script:Pause = $false
    $CancelButton.Enabled = $true
    $StartCopyButton.Enabled = $false

    Get-ChildItem -LiteralPath $Source -Recurse -File | ForEach {
        Copy-Item -Path $.FullName -Destination $NewDestination
        [System.Windows.Forms.Application]::DoEvents()
        while ($script:Pause -and !$script:CancelLoop) {
            [System.Windows.Forms.Application]::DoEvents()
            sleep 0.1
        }
        If($script:CancelLoop -eq $true) {
            #Exit the loop
            Break;
        }
    }
    $CancelButton.Enabled = $false
    $StartCopyButton.Enabled = $true
})

$CancelButton.Add_Click({
    $script:CancelLoop = $true
})
$PauseButton.Add_Click({
    $script:Pause = !$script:Pause
})

1
投票

实际上,您只需要一个按钮即可启动和暂停。这是一个非常基本的方法来说明我的想法,没有测试:

$script:CancelLoop = $false
$script:PauseLoop = $false
$CopyButton.Add_Click({
    # toggle the start/pause state when clicked
    $script:PauseLoop = -not $script:PauseLoop
    if ($script:PauseLoop) {
        $CancelButton.Enabled = $false
        $CopyButton.Text = "Start"
    }
    else {
        $CancelButton.Enabled = $true
        $CopyButton.Text = "Pause"
        # start / resume the loop
        Get-ChildItem $Source -Recurse -File | foreach {
            $newPath = Join-Path $NewDestination $_.Name
            # test if file was already copied
            # (might want to compare modified times too)
            if (-not (Test-Path $newPath)) {
                Copy-Item $_.FullName $newPath
            }
            [System.Windows.Forms.Application]::DoEvents()
            if ($script:CancelLoop -or $script:PauseLoop) {
                # exit loop if cancelled or paused
                break
            }
        }
        $CancelButton.Enabled = $false
        $CopyButton.Text = "Start"
    }
})

另一种方法是首先获取所有文件,将它们保存在集合中,然后在该点存储索引和暂停/恢复。但这带来了文件列表可能在此期间发生变化的风险。因此,真正“安全”的解决方案会更复杂。

© www.soinside.com 2019 - 2024. All rights reserved.