I have a script that uses windows forms and runspace. I can’t realize that after clicking on “Clean Now” button my gif picture would keep rotating and after ExitCode 0 I would get Show-SuccessForm (function in my code) but Show-SuccessForm just refuses to appear. I’m sure that ExitCode 0 is visible in debugging What could be the reason?
<code>Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Create the form
$form = New-Object System.Windows.Forms.Form
$form.Text = "Periodic Control"
$form.Size = New-Object System.Drawing.Size(400, 300)
$form.StartPosition = "CenterScreen"
$form.TopMost = $true
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
$form.MaximizeBox = $false
$form.MinimizeBox = $false
# Create the exclamation icon
$iconLabel = New-Object System.Windows.Forms.Label
$iconLabel.Size = New-Object System.Drawing.Size(32, 32)
$iconLabel.Location = New-Object System.Drawing.Point(10, 10)
$iconLabel.Image = [System.Drawing.SystemIcons]::Exclamation.ToBitmap()
$form.Controls.Add($iconLabel)
# Determine the text based on system language
$language = [System.Globalization.CultureInfo]::CurrentUICulture.TwoLetterISOLanguageName
switch ($language) {
"ru" {
# $text =
}
"uk" {
# $text =
}
default {
$text = "text"
}
}
# Create the notification text
$label = New-Object System.Windows.Forms.Label
$label.Size = New-Object System.Drawing.Size(360, 100)
$label.Location = New-Object System.Drawing.Point(50, 10)
$label.Text = $text
$form.Controls.Add($label)
# Create the timer label
$timerLabel = New-Object System.Windows.Forms.Label
$timerLabel.Size = New-Object System.Drawing.Size(360, 30)
$timerLabel.Location = New-Object System.Drawing.Point(50, 120)
$form.Controls.Add($timerLabel)
$timeLeft = 60 * 60 # 60 minutes in seconds
# Create the progress bar
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Size = New-Object System.Drawing.Size(300, 30)
$progressBar.Location = New-Object System.Drawing.Point(50, 150)
$progressBar.Minimum = 0
$progressBar.Maximum = $timeLeft
$progressBar.Value = $timeLeft
$form.Controls.Add($progressBar)
# Function to update the timer
function Update-Timer {
$global:timeLeft -= 1
$minutes = [math]::Floor($global:timeLeft / 60)
$seconds = $global:timeLeft % 60
$timerLabel.Text = "Time remaining: $minutes minutes $seconds seconds"
$progressBar.Value = $global:timeLeft
if ($global:timeLeft -le 0) {
$timer.Stop()
[System.Windows.Forms.MessageBox]::Show("Cleaning started")
# Add script for actual cleaning here
}
}
# Create the timer
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000
$timer.Add_Tick({
Update-Timer
})
$timer.Start()
# Initial timer setup
Update-Timer
# Create the "Clean Now" button
$button = New-Object System.Windows.Forms.Button
$button.Size = New-Object System.Drawing.Size(100, 30)
$button.Location = New-Object System.Drawing.Point(150, 200)
$button.Text = "Clean Now"
$form.Controls.Add($button)
# Create the spinner PictureBox
$spinner = New-Object System.Windows.Forms.PictureBox
$spinner.AutoSize = $true
$spinner.Location = New-Object System.Drawing.Point(150, 100)
$SpinnergifLink = 'C:WindowsTempSpinner.gif'
$Spinnerimg = [System.Drawing.Image]::FromFile($SpinnergifLink)
$spinner.Image = $Spinnerimg
$spinner.Visible = $false
$form.Controls.Add($spinner)
# Create the processing label
$processingLabel = New-Object System.Windows.Forms.Label
$processingLabel.Size = New-Object System.Drawing.Size(300, 30)
$processingLabel.Location = New-Object System.Drawing.Point(100, 60)
$processingLabel.Font = [System.Drawing.Font]::new("Bold", 12, [System.Drawing.FontStyle]::Bold)
$processingLabel.Text = "Clean files processing..."
$processingLabel.Visible = $false
$form.Controls.Add($processingLabel)
# Function to handle cleaning process
function Run-CleanProcess {
$spinner.Visible = $true
$processingLabel.Visible = $true
$label.Visible = $false
$timerLabel.Visible = $false
$progressBar.Visible = $false
$button.Visible = $false
$scriptBlock = {
$StartClearFiles = Start-Process powershell.exe -ArgumentList "-ExecutionPolicy Bypass", "-File C:WindowsTempClearJob.ps1" -NoNewWindow -Wait -PassThru
return $StartClearFiles.ExitCode
}
$runspace = [powershell]::Create().AddScript($scriptBlock)
$asyncResult = $runspace.BeginInvoke()
$timerCheck = New-Object System.Windows.Forms.Timer
$timerCheck.Interval = 500 # Check every 500 milliseconds
$timerCheck.Add_Tick({
if($asyncResult.IsCompleted -eq $true) {
$exitCode = $runspace.EndInvoke($asyncResult)
$runspace.runspace.dispose()
if ($exitcode -eq 0) {
Show-SuccessForm
}
else {
[System.Windows.Forms.MessageBox]::Show("Cleaning failed.")
}
}
})
}
# Function to show success message
function Show-SuccessForm {
$successForm = New-Object System.Windows.Forms.Form
$successForm.Text = "Success"
$successForm.Size = New-Object System.Drawing.Size(300, 150)
$successForm.StartPosition = "CenterScreen"
$successForm.TopMost = $true
$successForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
$successForm.MaximizeBox = $false
$successForm.MinimizeBox = $false
$successLabel = New-Object System.Windows.Forms.Label
$successLabel.Size = New-Object System.Drawing.Size(260, 50)
$successLabel.Location = New-Object System.Drawing.Point(20, 20)
$successLabel.Text = "Success"
$successForm.Controls.Add($successLabel)
$okButton = New-Object System.Windows.Forms.Button
$okButton.Size = New-Object System.Drawing.Size(100, 30)
$okButton.Location = New-Object System.Drawing.Point(100, 80)
$okButton.Text = "OK"
$okButton.Add_Click({
$successForm.Close()
})
$successForm.Controls.Add($okButton)
[void]$successForm.ShowDialog()
}
$button.Add_Click({
$timer.Stop()
Run-CleanProcess
})
# Form closing event handler to prevent closing
$form.Add_FormClosing({
$_.Cancel = $false # Cancel form closing
})
# Show the form
[void]$form.ShowDialog()
</code>
<code>Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Create the form
$form = New-Object System.Windows.Forms.Form
$form.Text = "Periodic Control"
$form.Size = New-Object System.Drawing.Size(400, 300)
$form.StartPosition = "CenterScreen"
$form.TopMost = $true
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
$form.MaximizeBox = $false
$form.MinimizeBox = $false
# Create the exclamation icon
$iconLabel = New-Object System.Windows.Forms.Label
$iconLabel.Size = New-Object System.Drawing.Size(32, 32)
$iconLabel.Location = New-Object System.Drawing.Point(10, 10)
$iconLabel.Image = [System.Drawing.SystemIcons]::Exclamation.ToBitmap()
$form.Controls.Add($iconLabel)
# Determine the text based on system language
$language = [System.Globalization.CultureInfo]::CurrentUICulture.TwoLetterISOLanguageName
switch ($language) {
"ru" {
# $text =
}
"uk" {
# $text =
}
default {
$text = "text"
}
}
# Create the notification text
$label = New-Object System.Windows.Forms.Label
$label.Size = New-Object System.Drawing.Size(360, 100)
$label.Location = New-Object System.Drawing.Point(50, 10)
$label.Text = $text
$form.Controls.Add($label)
# Create the timer label
$timerLabel = New-Object System.Windows.Forms.Label
$timerLabel.Size = New-Object System.Drawing.Size(360, 30)
$timerLabel.Location = New-Object System.Drawing.Point(50, 120)
$form.Controls.Add($timerLabel)
$timeLeft = 60 * 60 # 60 minutes in seconds
# Create the progress bar
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Size = New-Object System.Drawing.Size(300, 30)
$progressBar.Location = New-Object System.Drawing.Point(50, 150)
$progressBar.Minimum = 0
$progressBar.Maximum = $timeLeft
$progressBar.Value = $timeLeft
$form.Controls.Add($progressBar)
# Function to update the timer
function Update-Timer {
$global:timeLeft -= 1
$minutes = [math]::Floor($global:timeLeft / 60)
$seconds = $global:timeLeft % 60
$timerLabel.Text = "Time remaining: $minutes minutes $seconds seconds"
$progressBar.Value = $global:timeLeft
if ($global:timeLeft -le 0) {
$timer.Stop()
[System.Windows.Forms.MessageBox]::Show("Cleaning started")
# Add script for actual cleaning here
}
}
# Create the timer
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000
$timer.Add_Tick({
Update-Timer
})
$timer.Start()
# Initial timer setup
Update-Timer
# Create the "Clean Now" button
$button = New-Object System.Windows.Forms.Button
$button.Size = New-Object System.Drawing.Size(100, 30)
$button.Location = New-Object System.Drawing.Point(150, 200)
$button.Text = "Clean Now"
$form.Controls.Add($button)
# Create the spinner PictureBox
$spinner = New-Object System.Windows.Forms.PictureBox
$spinner.AutoSize = $true
$spinner.Location = New-Object System.Drawing.Point(150, 100)
$SpinnergifLink = 'C:WindowsTempSpinner.gif'
$Spinnerimg = [System.Drawing.Image]::FromFile($SpinnergifLink)
$spinner.Image = $Spinnerimg
$spinner.Visible = $false
$form.Controls.Add($spinner)
# Create the processing label
$processingLabel = New-Object System.Windows.Forms.Label
$processingLabel.Size = New-Object System.Drawing.Size(300, 30)
$processingLabel.Location = New-Object System.Drawing.Point(100, 60)
$processingLabel.Font = [System.Drawing.Font]::new("Bold", 12, [System.Drawing.FontStyle]::Bold)
$processingLabel.Text = "Clean files processing..."
$processingLabel.Visible = $false
$form.Controls.Add($processingLabel)
# Function to handle cleaning process
function Run-CleanProcess {
$spinner.Visible = $true
$processingLabel.Visible = $true
$label.Visible = $false
$timerLabel.Visible = $false
$progressBar.Visible = $false
$button.Visible = $false
$scriptBlock = {
$StartClearFiles = Start-Process powershell.exe -ArgumentList "-ExecutionPolicy Bypass", "-File C:WindowsTempClearJob.ps1" -NoNewWindow -Wait -PassThru
return $StartClearFiles.ExitCode
}
$runspace = [powershell]::Create().AddScript($scriptBlock)
$asyncResult = $runspace.BeginInvoke()
$timerCheck = New-Object System.Windows.Forms.Timer
$timerCheck.Interval = 500 # Check every 500 milliseconds
$timerCheck.Add_Tick({
if($asyncResult.IsCompleted -eq $true) {
$exitCode = $runspace.EndInvoke($asyncResult)
$runspace.runspace.dispose()
if ($exitcode -eq 0) {
Show-SuccessForm
}
else {
[System.Windows.Forms.MessageBox]::Show("Cleaning failed.")
}
}
})
}
# Function to show success message
function Show-SuccessForm {
$successForm = New-Object System.Windows.Forms.Form
$successForm.Text = "Success"
$successForm.Size = New-Object System.Drawing.Size(300, 150)
$successForm.StartPosition = "CenterScreen"
$successForm.TopMost = $true
$successForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
$successForm.MaximizeBox = $false
$successForm.MinimizeBox = $false
$successLabel = New-Object System.Windows.Forms.Label
$successLabel.Size = New-Object System.Drawing.Size(260, 50)
$successLabel.Location = New-Object System.Drawing.Point(20, 20)
$successLabel.Text = "Success"
$successForm.Controls.Add($successLabel)
$okButton = New-Object System.Windows.Forms.Button
$okButton.Size = New-Object System.Drawing.Size(100, 30)
$okButton.Location = New-Object System.Drawing.Point(100, 80)
$okButton.Text = "OK"
$okButton.Add_Click({
$successForm.Close()
})
$successForm.Controls.Add($okButton)
[void]$successForm.ShowDialog()
}
$button.Add_Click({
$timer.Stop()
Run-CleanProcess
})
# Form closing event handler to prevent closing
$form.Add_FormClosing({
$_.Cancel = $false # Cancel form closing
})
# Show the form
[void]$form.ShowDialog()
</code>
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Create the form
$form = New-Object System.Windows.Forms.Form
$form.Text = "Periodic Control"
$form.Size = New-Object System.Drawing.Size(400, 300)
$form.StartPosition = "CenterScreen"
$form.TopMost = $true
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
$form.MaximizeBox = $false
$form.MinimizeBox = $false
# Create the exclamation icon
$iconLabel = New-Object System.Windows.Forms.Label
$iconLabel.Size = New-Object System.Drawing.Size(32, 32)
$iconLabel.Location = New-Object System.Drawing.Point(10, 10)
$iconLabel.Image = [System.Drawing.SystemIcons]::Exclamation.ToBitmap()
$form.Controls.Add($iconLabel)
# Determine the text based on system language
$language = [System.Globalization.CultureInfo]::CurrentUICulture.TwoLetterISOLanguageName
switch ($language) {
"ru" {
# $text =
}
"uk" {
# $text =
}
default {
$text = "text"
}
}
# Create the notification text
$label = New-Object System.Windows.Forms.Label
$label.Size = New-Object System.Drawing.Size(360, 100)
$label.Location = New-Object System.Drawing.Point(50, 10)
$label.Text = $text
$form.Controls.Add($label)
# Create the timer label
$timerLabel = New-Object System.Windows.Forms.Label
$timerLabel.Size = New-Object System.Drawing.Size(360, 30)
$timerLabel.Location = New-Object System.Drawing.Point(50, 120)
$form.Controls.Add($timerLabel)
$timeLeft = 60 * 60 # 60 minutes in seconds
# Create the progress bar
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Size = New-Object System.Drawing.Size(300, 30)
$progressBar.Location = New-Object System.Drawing.Point(50, 150)
$progressBar.Minimum = 0
$progressBar.Maximum = $timeLeft
$progressBar.Value = $timeLeft
$form.Controls.Add($progressBar)
# Function to update the timer
function Update-Timer {
$global:timeLeft -= 1
$minutes = [math]::Floor($global:timeLeft / 60)
$seconds = $global:timeLeft % 60
$timerLabel.Text = "Time remaining: $minutes minutes $seconds seconds"
$progressBar.Value = $global:timeLeft
if ($global:timeLeft -le 0) {
$timer.Stop()
[System.Windows.Forms.MessageBox]::Show("Cleaning started")
# Add script for actual cleaning here
}
}
# Create the timer
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = 1000
$timer.Add_Tick({
Update-Timer
})
$timer.Start()
# Initial timer setup
Update-Timer
# Create the "Clean Now" button
$button = New-Object System.Windows.Forms.Button
$button.Size = New-Object System.Drawing.Size(100, 30)
$button.Location = New-Object System.Drawing.Point(150, 200)
$button.Text = "Clean Now"
$form.Controls.Add($button)
# Create the spinner PictureBox
$spinner = New-Object System.Windows.Forms.PictureBox
$spinner.AutoSize = $true
$spinner.Location = New-Object System.Drawing.Point(150, 100)
$SpinnergifLink = 'C:WindowsTempSpinner.gif'
$Spinnerimg = [System.Drawing.Image]::FromFile($SpinnergifLink)
$spinner.Image = $Spinnerimg
$spinner.Visible = $false
$form.Controls.Add($spinner)
# Create the processing label
$processingLabel = New-Object System.Windows.Forms.Label
$processingLabel.Size = New-Object System.Drawing.Size(300, 30)
$processingLabel.Location = New-Object System.Drawing.Point(100, 60)
$processingLabel.Font = [System.Drawing.Font]::new("Bold", 12, [System.Drawing.FontStyle]::Bold)
$processingLabel.Text = "Clean files processing..."
$processingLabel.Visible = $false
$form.Controls.Add($processingLabel)
# Function to handle cleaning process
function Run-CleanProcess {
$spinner.Visible = $true
$processingLabel.Visible = $true
$label.Visible = $false
$timerLabel.Visible = $false
$progressBar.Visible = $false
$button.Visible = $false
$scriptBlock = {
$StartClearFiles = Start-Process powershell.exe -ArgumentList "-ExecutionPolicy Bypass", "-File C:WindowsTempClearJob.ps1" -NoNewWindow -Wait -PassThru
return $StartClearFiles.ExitCode
}
$runspace = [powershell]::Create().AddScript($scriptBlock)
$asyncResult = $runspace.BeginInvoke()
$timerCheck = New-Object System.Windows.Forms.Timer
$timerCheck.Interval = 500 # Check every 500 milliseconds
$timerCheck.Add_Tick({
if($asyncResult.IsCompleted -eq $true) {
$exitCode = $runspace.EndInvoke($asyncResult)
$runspace.runspace.dispose()
if ($exitcode -eq 0) {
Show-SuccessForm
}
else {
[System.Windows.Forms.MessageBox]::Show("Cleaning failed.")
}
}
})
}
# Function to show success message
function Show-SuccessForm {
$successForm = New-Object System.Windows.Forms.Form
$successForm.Text = "Success"
$successForm.Size = New-Object System.Drawing.Size(300, 150)
$successForm.StartPosition = "CenterScreen"
$successForm.TopMost = $true
$successForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
$successForm.MaximizeBox = $false
$successForm.MinimizeBox = $false
$successLabel = New-Object System.Windows.Forms.Label
$successLabel.Size = New-Object System.Drawing.Size(260, 50)
$successLabel.Location = New-Object System.Drawing.Point(20, 20)
$successLabel.Text = "Success"
$successForm.Controls.Add($successLabel)
$okButton = New-Object System.Windows.Forms.Button
$okButton.Size = New-Object System.Drawing.Size(100, 30)
$okButton.Location = New-Object System.Drawing.Point(100, 80)
$okButton.Text = "OK"
$okButton.Add_Click({
$successForm.Close()
})
$successForm.Controls.Add($okButton)
[void]$successForm.ShowDialog()
}
$button.Add_Click({
$timer.Stop()
Run-CleanProcess
})
# Form closing event handler to prevent closing
$form.Add_FormClosing({
$_.Cancel = $false # Cancel form closing
})
# Show the form
[void]$form.ShowDialog()
I tried using while but it caused the form to stop updating and my picture hangs up
<code> $scriptBlock = {
$StartClearFiles = Start-Process powershell.exe -ArgumentList "-ExecutionPolicy Bypass", "-File C:WindowsTempClearJob.ps1" -NoNewWindow -Wait -PassThru
return $startClearFiles.ExitCode
}
$runspace = [powershell]::Create().AddScript($scriptBlock)
$asyncResult = $runspace.BeginInvoke()
while ($asyncResult.IsCompleted -notcontains $true) {}
$exitCode = $runspace.EndInvoke($asyncResult)
$runspace.Dispose()
if ($exitcode -eq 0) {
Show-SuccessForm
$form.Add_FormClosing({
$_.Cancel = $false # Enable form closing
})
$form.Close()
}
</code>
<code> $scriptBlock = {
$StartClearFiles = Start-Process powershell.exe -ArgumentList "-ExecutionPolicy Bypass", "-File C:WindowsTempClearJob.ps1" -NoNewWindow -Wait -PassThru
return $startClearFiles.ExitCode
}
$runspace = [powershell]::Create().AddScript($scriptBlock)
$asyncResult = $runspace.BeginInvoke()
while ($asyncResult.IsCompleted -notcontains $true) {}
$exitCode = $runspace.EndInvoke($asyncResult)
$runspace.Dispose()
if ($exitcode -eq 0) {
Show-SuccessForm
$form.Add_FormClosing({
$_.Cancel = $false # Enable form closing
})
$form.Close()
}
</code>
$scriptBlock = {
$StartClearFiles = Start-Process powershell.exe -ArgumentList "-ExecutionPolicy Bypass", "-File C:WindowsTempClearJob.ps1" -NoNewWindow -Wait -PassThru
return $startClearFiles.ExitCode
}
$runspace = [powershell]::Create().AddScript($scriptBlock)
$asyncResult = $runspace.BeginInvoke()
while ($asyncResult.IsCompleted -notcontains $true) {}
$exitCode = $runspace.EndInvoke($asyncResult)
$runspace.Dispose()
if ($exitcode -eq 0) {
Show-SuccessForm
$form.Add_FormClosing({
$_.Cancel = $false # Enable form closing
})
$form.Close()
}