0

Following on from a previous question The actual code is a lot more complex, but the following is working example of my loop:

Add-Type -AssemblyName System.Windows.Forms
$source = '\\servera\files'
$destination = '\\server b\files'
$form = New-Object System.Windows.Forms.Form

$CopyOutput = New-Object System.Windows.Forms.Label
$CopyOutput.Location = '10,15'
$CopyOutput.Size = '350,20'

$form.Text = "$DomainName Folder/Archive Copy"
$form.Size = '380,130'
$form.CancelButton = $ExitButton
$form.Add_FormClosing({
    $script:CancelLoop = $true
}) 

$StartButton = New-Object System.Windows.Forms.Button
$StartButton.Name = 'StartButton'
$StartButton.Location = '10,50'
$StartButton.Size = '75,23'
$StartButton.Text = 'Start Copy'
$StartButton.Enabled = $true

$PauseButton = New-Object System.Windows.Forms.Button
$PauseButton.Location = '100,50'
$PauseButton.Size = '75,23'
$PauseButton.Text = 'Pause Copy'
$PauseButton.Enabled = $true

$StopButton = New-Object System.Windows.Forms.Button
$StopButton.Location = '190,50'
$StopButton.Size = '75,23'
$StopButton.Text = 'Stop Copy'
$StopButton.Enabled = $true

$ExitButton = New-Object System.Windows.Forms.Button
$ExitButton.Name = 'ExitButton'
$ExitButton.Location = '280,50'
$ExitButton.Size = '75,23'
$ExitButton.Text = 'Exit'
$ExitButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.Controls.AddRange(@($StartButton,$PauseButton,$StopButton,$ExitButton,$CopyOutput))

$StopButton.Add_Click({
    $script:PauseToggle = $false
    $script:CancelLoop = $true
})
$PauseButton.Add_Click({
# Boolean change value to true/false
    $script:PauseToggle = !$script:PauseToggle
})

$StartButton.Add_Click({
    $script:CancelLoop = $false
    $script:PauseToggle = $false
    $StopButton.Enabled = $true
    $StartButton.Enabled = $false

Get-ChildItem -LiteralPath $Source -Recurse -File | ForEach {
    Copy-Item -LiteralPath $_.FullName -Destination $Destination
    $CopyOutput.Text = ('Copying' + $_.FullName)
    [System.Windows.Forms.Application]::DoEvents()
    If($script:CancelLoop -eq $true) {
        $CopyOutput.Text = 'Cancel copy'
        #Exit the loop
        Break;
    }
    If ($script:PauseToggle) {
        $CopyOutput.Text = 'Paused'
        Do { 
        [System.Windows.Forms.Application]::DoEvents()
        } Until (!$script:PauseToggle)
    }
}
$CancelButton.Enabled = $false
$StartCopyButton.Enabled = $true
})
$form.ShowDialog() 
$form.Dispose()

All the articles I can find say that this code should work ok - can anyone advise how to avoid the unhandled exception which results when the "Stop" button is pressed?

All the articles I can find say that this code should work ok - can anyone advise how to avoid the unhandled exception which results when the "Stop" button is pressed?

Scepticalist
  • 3,737
  • 1
  • 13
  • 30

1 Answers1

0

From what I can see in my research, this is an issue with using BREAK in forms. I did however find a workaround from here

Using this commandlet will stop the current pipeline instead of using BREAK

Filter Stop-Pipeline {
    $sp = { Select-Object -First 1 }.GetSteppablePipeline($MyInvocation.CommandOrigin)
    $sp.Begin($true)
    $sp.Process(0)
}
Scepticalist
  • 3,737
  • 1
  • 13
  • 30