We don't know the specifics of how your GUI is displayed, but, assuming you're using a WinForms GUI constructed in PowerShell code, your problem may be how your GUI construction code loads images from files in the folder that you later want to delete.
Notably, if you use something like:
[Bitmap]::new(<file-path>)
[System.Drawing.Image]::FromFile(<file-path>)
the specified file apparently stays open for the remainder of the PowerShell session, and you won't be able to delete your folder.
The solution is to create a new image instance in memory that copies the loaded-from-file image, and to then dispose of the loaded-from-file image, which releases the lock on the underlying file, as demonstrated in this [C#] answer.
Here's a minimal script, demo.ps1
, that demonstrates the approach:
Save it to its own, temporary, throw-away folder.
Copy a small image file named demo.png
into the same folder.
Then invoke it as <temp-folder>/demo -SelfDestruct
to see it in action; the need to specify
-SelfDescript
is a precaution, given that accidental invocation would wipe out the entire folder in which the script lives.
demo.ps1
:
param([switch] $SelfDestruct)
# Load the WinForms assembly.
Add-Type -AssemblyName System.Windows.Forms
# Create the form.
$form = New-Object system.Windows.Forms.Form -Property @{
ClientSize = New-Object System.Drawing.Point 400,100
Text = "Dialog"
}
# Add a PictureBox control that loads its image from 'demo.png'
$form.Controls.Add((New-Object System.Windows.Forms.PictureBox -Property @{
Image = & {
# Load the image from file in the same folder as a script into
# a temporary variable.
$tmpImg = [System.Drawing.Image]::FromFile((Join-Path $PSScriptRoot 'demo.png'))
# Create an in-memory copy of the image.
New-Object System.Drawing.Bitmap $tmpImg
# Dispose of the from-file image, which releases the file.
$tmpImg.Dispose()
}
Location = New-Object System.Drawing.Point 10, 10
}))
# Show the form and wait for the use to close it.
$null = $form.ShowDialog()
if ($SelfDestruct) { # Remove the running script's entire folder.
if ("$($PWD.Path)\" -like "$PSScriptRoot\*") { #"
Push-Location C:\ # must switch to different dir. before deleting.
}
# Remove the entire folder.
Remove-Item -literalpath $PSScriptRoot -Recurse -Force
exit
}
Here's a variant that triggers the removal by button click, via an event handler:
param([switch] $SelfDestruct)
Add-Type -AssemblyName System.Windows.Forms
function remove-OwnFolder {
# If the current dir. is in the subtree of the folder to delete,
# we must switch to different dir. before deleting.
if ("$($PWD.Path)\" -like "$PSScriptRoot\*") { #"
Push-Location C:\
}
# Remove the script's parent folder as a whole.
Remove-Item -literalpath $PSScriptRoot -Recurse -Force
}
# Create the form.
$form = New-Object system.Windows.Forms.Form -Property @{
ClientSize = New-Object System.Drawing.Point 400,100
Text = "Dialog"
}
# Add a PictureBox control that loads its image from 'demo.png'
$form.Controls.Add((New-Object System.Windows.Forms.PictureBox -Property @{
Image = & {
# Load the image from file in the same folder as a script into
# a temporary variable.
$tmpImg = [System.Drawing.Image]::FromFile((Join-Path $PSScriptRoot 'demo.png'))
# Create an in-memory copy of the image.
New-Object System.Drawing.Bitmap $tmpImg
# Dispose of the from-file image, which releases the file.
$tmpImg.Dispose()
}
Location = New-Object System.Drawing.Point 10, 10
}))
# Add a button that will trigger the self-destruction
$btnSelfDestruct = New-Object system.Windows.Forms.Button -Property @{
Text = "Submit"
Location = New-Object System.Drawing.Point 160, 60
}
$form.Controls.Add($btnSelfDestruct)
# Add the button-click event handler.
$btnSelfDestruct.Add_Click({
$form.Close()
if ($SelfDestruct) {
remove-OwnFolder
}
exit
})
# Show the form and wait for the use to close it.
$null = $form.ShowDialog()