Jonas
Jonas

Reputation: 186

Process locking temporary file. How can i get around this?

As part of looking into creating a GUI for handling certain repetitive tasks i made for for a eight ball function. As part of this function i use an background image and an icon that is embedded in the script and written to $env:tmp.

Upon exit from the GUI i have a cleanup to remove the temporary files. However the script is unable to delete the background image while PowerShell is running even when the form has been terminated.¨

Remove-Item : Cannot remove item C:\Users\USERNAME\AppData\Local\Temp\11a8093b2817a3e1ff135fec4fe01320.jpg: The process cannot access the file 'C:\Users\USERNAME\AppData\Local\Temp\1
1a8093b2817a3e1ff135fec4fe01320.jpg' because it is being used by another process.
At C:\Users\USERNAME\Desktop\8ball.ps1:89 char:1
+ Remove-Item "$env:temp\11a8093b2817a3e1ff135fec4fe01320.jpg"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (C:\Users\USERN~...fec4fe01320.jpg:FileInfo) [Remove-Item], IOException
    + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand

Is there any "simple" way i can get around this?

$MagicEightBallPicture = ""
$ContentPicture = [System.Convert]::FromBase64String($MagicEightBallPicture)
(Set-Content -Path $env:temp\11a8093b2817a3e1ff135fec4fe01320.jpg -Value $ContentPicture -Encoding Byte)

$MagicEightBallIcon = ""
$ContentIcon = [System.Convert]::FromBase64String($MagicEightBallIcon)
(Set-Content -Path $env:temp\11a8093b2817a3e1ff135fec4fe01320.ico -Value $ContentIcon -Encoding Byte)

$PossibleAnswers = @("It is certain",`
                     "It is decidedly so",`
                     "Without a doubt",`
                     "Yes, definitely",`
                     "You may rely on it",`
                     "As I see it, yes",`
                     "Most likely",`
                     "Outlook good",`
                     "Yes",`
                     "Signs point to yes",`
                     "Reply hazy try again",`
                     "Ask again later",`
                     "Better not tell you now",`
                     "Cannot predict now",`
                     "Concentrate and ask again",`
                     "Dont count on it",`
                     "My reply is no",`
                     "My sources say no",`
                     "Outlook not so good",`
                     "Very doubtful")

Function RollTheBall {

$TheAnswer = Get-Random -Count 1 -InputObject $PossibleAnswers
$TheAnswerBox.Text = $TheAnswer

}

Try {

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

$Image = [System.Drawing.Image]::Fromfile("$($env:temp)\11a8093b2817a3e1ff135fec4fe01320.jpg")
$Icon = New-Object System.Drawing.Icon ("$($env:temp)\11a8093b2817a3e1ff135fec4fe01320.ico")

$Form = New-Object System.Windows.Forms.Form
$Form.Text = "Magic Eight Ball"
$Form.MinimizeBox = $False
$Form.MaximizeBox = $False
$Form.FormBorderStyle = 'Fixed3D'
$Form.SizeGripStyle = "Hide"
$Form.ShowInTaskbar = $False
$Form.StartPosition = "CenterScreen"
$Form.Icon = $Icon
$Form.BackgroundImage = $Image
$Form.BackgroundImageLayout = "None"
$Form.Width = $Image.Width
$Form.Height = $Image.Hight

$Form.Size = New-Object System.Drawing.Size(300,200)

$TheAnswerBox = New-Object System.Windows.Forms.TextBox 
$TheAnswerBox.Location = New-Object System.Drawing.Size(10,10) 
$TheAnswerBox.Size = New-Object System.Drawing.Size(270,20)
$TheAnswerBox.TextAlign = [System.Windows.Forms.HorizontalAlignment]::Center
$TheAnswerBox.add_GotFocus({[System.Windows.Forms.SendKeys]::Send("{tab}")})
$Form.Controls.Add($TheAnswerBox)

$ButtonRollTheBall = New-Object System.Windows.Forms.Button 
$ButtonRollTheBall.Location = New-Object System.Drawing.Size(10,40) 
$ButtonRollTheBall.Size = New-Object System.Drawing.Size(130,20) 
$ButtonRollTheBall.Text = "Help?!" 
$ButtonRollTheBall.Add_Click({RollTheBall})
$Form.Controls.Add($ButtonRollTheBall)

$ButtonExit = New-Object System.Windows.Forms.Button 
$ButtonExit.Location = New-Object System.Drawing.Size(150,40) 
$ButtonExit.Size = New-Object System.Drawing.Size(130,20) 
$ButtonExit.Text = "Exit" 
$ButtonExit.Add_Click({$Form.Close()})
$Form.Controls.Add($ButtonExit)

$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()

} Finally {

Remove-Item "$env:temp\11a8093b2817a3e1ff135fec4fe01320.jpg"
Remove-Item "$env:temp\11a8093b2817a3e1ff135fec4fe01320.ico"

}

I've removed the embedded pictures due to possible copyright and shear size.

Upvotes: 2

Views: 580

Answers (1)

Martin Brandl
Martin Brandl

Reputation: 59031

Since the Image returned from [System.Drawing.Image]::Fromfile is disposable, you have to Dispose it to clean up the ressources before you delete it:

$Image.Dispose()

Upvotes: 1

Related Questions