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.
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()
Related
So I'm trying to insert red dots into some kind of map, which I do with creating new pictureboxes after reading their coordinates out of an txt-file.
My goal now is to remove or create new boxes, while the form.ShowDialog() was already used.
I found a way of closing the whole form and running everything again, which kind of works but is very ugly in my opinion. Was wondering if there is another way of checking if new coordinates have been added to the txt-file or removed and if that is the case, creating or removing the corresponding boxes.
(I tried .Refresh but that seems to do nothing at all)
function MakeForm {
[void][reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
[System.Windows.Forms.Application]::EnableVisualStyles();
$form = new-object Windows.Forms.Form
$form.Text = "Image Viewer"
$form.Width = 270;
$form.Height = 270;
$path = (Get-Item "Insert Path here")
$path2 = (Get-Item "Insert Path here")
$img = [System.Drawing.Image]::Fromfile($path);
$img2 = [System.Drawing.Image]::FromFile($path2);
$test = Get-Content -Path "Insert Path here"
$test
$pictureBoxes = New-Object 'System.Collections.Generic.List[Windows.Forms.PictureBox]'
$i=1
Foreach ($Line in $test){
if ($Line -like "*in 2*"){
$i++
$Split1= $Line.Split(" ")
$x=$Split1[5]
$y=$Split1[6]
$pictureBox = New-Object Windows.Forms.PictureBox
$pictureBox.Width = $img.Size.Width;
$pictureBox.Height = $img.Size.Height;
$pictureBox.Location = New-object System.Drawing.Size($x,$y)
$pictureBox.Image = $img;
$form.Controls.Add($pictureBox)
$pictureBoxes.Add($pictureBox)
Write-Host $pictureBoxes[$i]
$form.Add_Shown( { $form.Activate() } )
}
}
$pictureBox20 = New-Object Windows.Forms.PictureBox
$pictureBox20.Width = $img2.Size.Width;
$pictureBox20.Height = $img2.Size.Height;
$pictureBox20.Image = $img2;
$form.Controls.Add($pictureBox20)
$button1 = New-Object System.Windows.Forms.Button
$button1.Width=25
$button1.Height=223
$button1.Location = New-Object System.Drawing.Point(223,0)
$form.Controls.Add($button1)
$button1.Add_Click({
#Button for removing a box for testing purposes
$form.Controls.Remove($pictureBoxes[3])
})
$button2 = New-Object System.Windows.Forms.Button
$button2.Width=25
$button2.Height=223
$button2.Location = New-Object System.Drawing.Point(260,0)
$form.Controls.Add($button2)
$button2.Add_Click({
#This Button should refresh the whole form, if possible without doing everything again
$form.Close()
$form.Dispose()
MakeForm
})
$form.Add_Shown( { $form.Activate() } )
$form.ShowDialog()
}
MakeForm
I want to show the picturebox, but it does not show once I use form.show(). But if I change to Form.showdialog, the picturebox will show but, the process can not continue until I close the GUI. The picture box show but it does not moving, it stuck like picture.
Function Handling
{
$Form.Close()
$Form.Dispose()
$Form = New-Object system.Windows.Forms.Form
$Form.ControlBox = $true
$Form.BackColor = "#d0021b"
$Form.WindowState = "Maximized"
$Form.TopMost = $false
[void]$Form.Show()
# Message Box
[System.Windows.MessageBox]::Show("OK", "[Error]", "0", "Error")
$ExitCode = "1"
if($ExitCode -ne "107A")
{
$Form.Close()
$Form.Dispose()
Exit
}
else{
$Form.Close()
$Form.Dispose()
Exit
}
}
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$form.BackgroundImageLayout = 'Center'
$Form.WindowState = 'Maximized'
$Form.BackColor = "#ffffff"
$file2 = Get-ChildItem -Path "D:\3.png"
$cover = [Drawing.Image]::FromFile($file2)
$form.BackgroundImage = $img2
[reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$file = (get-item 'D:\6.gif')
$img = [System.Drawing.Image]::Fromfile($file)
$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.Image = $img
$pictureBox.SizeMode = "Autosize"
$pictureBox.Anchor = "Bottom, left"
$Form.controls.add($pictureBox)
[reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$file3 = (get-item 'D:\6.gif')
$img3 = [System.Drawing.Image]::Fromfile($file3)
$pictureBox2 = new-object Windows.Forms.PictureBox
$pictureBox2.Image = $img3
$pictureBox2.SizeMode = "Autosize"
$pictureBox2.Anchor = "Bottom, right"
$Form.controls.add($pictureBox2)
$form.Show()
Write-Host "next process"
####
# some process
###
Start-Sleep -s 2
Handling
Anyone can give me idea please. Really appreciate for your help. Thank you.
Can you try like this? Put your background operation in place of Start-Sleep -s 2 and the gif file still show moving.
$Form = New-Object system.Windows.Forms.Form
$Form.Location= New-Object System.Drawing.Size(100,100)
$Form.Size= New-Object System.Drawing.Size(550,170)
$Form.StartPosition = "Manual"
$Form.Visible=$false
$Form.Enabled = $true
$Form.Add_Shown({$Form.Activate()})
[reflection.assembly]::LoadWithPartialName("System.Windows.Forms")
$file = (get-item 'D:\6.gif')
$img = [System.Drawing.Image]::Fromfile($file);
[System.Windows.Forms.Application]::EnableVisualStyles();
$pictureBox = new-object Windows.Forms.PictureBox
$pictureBox.Location = New-Object System.Drawing.Size(0,1)
$pictureBox.Size = New-Object System.Drawing.Size($img.Width,$img.Height)
$pictureBox.Image = $img
$Form.controls.add($pictureBox)
$WaitForm.Topmost = $True
$rs = [Management.Automation.Runspaces.RunspaceFactory]::CreateRunspace()
$rs.Open()
$rs.SessionStateProxy.SetVariable("Form", $Form)
$data = [hashtable]::Synchronized(#{text=""})
$rs.SessionStateProxy.SetVariable("data", $data)
$p = $rs.CreatePipeline({ [void] $Form.ShowDialog()})
$p.Input.Close()
$p.InvokeAsync()
## Enter the rest of your script here while you want the form to display
Start-Sleep -s 2
$WaitForm.close()
I am a very new to powershell. I was tasked with creating a GUI that takes in several strings from multiple drop-downs and renames the computer according to those choices. I am testing it with two options, $FacilityInitials and $BuildingNumber. Powershell is returning only the $BuildingNumber choice.
I may be doing something wrong with returning? How should I do multiple return fuctions properly? Thank you! :)
I tried checking for typos.
#Edit This item to change the DropDown Values
[array]$DropDownArray1 = "LI", "BE", "HA"
# This Function Returns the Selected Value and Closes the Form
function Return-DropDown {
$script:Choice = $DropDown1.SelectedItem.ToString()
$Form.Close()
}
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$Form = New-Object System.Windows.Forms.Form
$Form.width = 350
$Form.height = 200
$Form.Text = ”Computer Renamer”
$DropDown1 = new-object System.Windows.Forms.ComboBox
$DropDown1.Location = new-object System.Drawing.Size(100,30)
$DropDown1.Size = new-object System.Drawing.Size(130,30)
ForEach ($Item in $DropDownArray1) {
[void] $DropDown1.Items.Add($Item)
}
$Form.Controls.Add($DropDown1)
$DropDown1Label = new-object System.Windows.Forms.Label
$DropDown1Label.Location = new-object System.Drawing.Size(10,30)
$DropDown1Label.size = new-object System.Drawing.Size(100,20)
$DropDown1Label.Text = "Facility Initials:"
$Form.Controls.Add($DropDown1Label)
################################################################################
#Edit This item to change the DropDown Values
[array]$DropDownArray2 = "01", "02", "03"
# This Function Returns the Selected Value and Closes the Form
function Return-DropDown {
$script:Choice2 = $DropDown2.SelectedItem.ToString()
$Form.Close()
}
$DropDown2 = new-object System.Windows.Forms.ComboBox
$DropDown2.Location = new-object System.Drawing.Size(100,60)
$DropDown2.Size = new-object System.Drawing.Size(130,30)
ForEach ($Item in $DropDownArray2) {
[void] $DropDown2.Items.Add($Item)
}
$Form.Controls.Add($DropDown2)
$DropDown2Label = new-object System.Windows.Forms.Label
$DropDown2Label.Location = new-object System.Drawing.Size(10,60)
$DropDown2Label.size = new-object System.Drawing.Size(100,20)
$DropDown2Label.Text = "Building Number:"
$Form.Controls.Add($DropDown2Label)
################################################################################
#Button
$Button = new-object System.Windows.Forms.Button
$Button.Location = new-object System.Drawing.Size(100,130)
$Button.Size = new-object System.Drawing.Size(150,20)
$Button.Text = "Rename Computer"
$Button.Add_Click({Return-DropDown})
$form.Controls.Add($Button)
################################################################################
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()
$FacilityInitials = $Choice
$BuildingNumber = $Choice2
$newCompName = $FacilityInitials + "-" + $BuildingNumber
$AdminAcc = ""
#Add Restart and Force later
Rename-Computer -NewName $newCompName -DomainCredential $AdminAcc
I am working on a PowerShell application which should take a user id as input from a text box, then search ActiveDirectory and return three fields; however, every time I try to use it I receive the following error:
Get-ADUser : Cannot validate argument on parameter 'Identity'. The argument is null. Provide a valid value for the argument, and then try running the command again.
At C:\Path\cc-lookup-gui.ps1:40 char:21
+ $y = Get-ADUser $script:x -Properties cC
+ ~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
Here is the code for my GUI and search function:
[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")|Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")|Out-Null
$net = New-Object -ComObject Wscript.Network
$form = New-Object System.Windows.Forms.Form
$form.Width = 525
$form.Height = 350
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::Fixed3D
$form.Text = "CC Lookup"
$form.MaximumSize = New-Object System.Drawing.Size(525,350)
$form.StartPosition = "centerscreen"
$form.KeyPreview = $true
$form.Add_KeyDown({if($_.KeyCode -eq "Enter"){$script:x=$input.Text;Search}})
$form.Add_KeyDown({if($_.KeyCode -eq "Escape"){$form.Close()}})
$input = new-object System.Windows.Forms.TextBox
$input.maxLength = 6
$input.Location = New-Object System.Drawing.Size(200,75)
add-type -assemblyName System.Windows.Forms
$label1 = New-Object System.Windows.Forms.Label
$label1.Location = New-Object System.Drawing.Size(200,25)
$label1.AutoSize = $true
$label1.Text = "Enter User ID:"
$Button1 = new-object System.Windows.Forms.Button
$Button1.Location = New-Object System.Drawing.Size(100,132)
$Button1.Size = New-Object System.Drawing.Size(80,20)
$Button1.Text = "Search"
$Button1.Add_Click({$script:x=$input.Text;Search})
$button2 = New-Object System.Windows.Forms.Button
$button2.Location = New-Object System.Drawing.Size(300,132)
$button2.Text = "Clear"
$button2.Add_Click({Clears})
function Search{
$y = Get-ADUser $script:x -Properties cC
$output = $y.samAccountName + '|' + $y.CN + '|' + $y.cC
Add-Type -AssemblyName System.Windows.Forms
$label = New-Object System.Windows.Forms.Label
$label.Text = $Output
$label.AutoSize = $true
$label.Location = New-Object System.Drawing.Size(200,100)
$form.controls.add($label)
}
function Clears{
$label.Text = $null
$input.Text = $null
}
$form.Controls.Add($label1)
$form.Controls.Add($button2)
$form.Controls.Add($input)
$form.Controls.Add($Button1)
$form.Add_Shown({$Form.Activate()})
$Form.ShowDialog()
$x = $input.Text
I have tried declaring the variable $x globally, directly calling $input.text for the search function, and converting $x into a string, all of which return this same error. I'm running PowerShell version 5.
$Input is a special variable name - see help about_Automatic_Variables - and won't do what you expect when you use it in your {} scriptblock, it will refer to scriptblock input (in this case, nothing), instead of your inputbox.
Try renaming it to something else.
im creating a gui script for users to get certain files, its not finished yet but i have a problem i cant solve.
i want to have choices of which file they want + an option for them to insert a name that they want for the file that they chose.
the problem is the text box is cut in the middle and only if you write a lot you will see the end of your text.
please help! thanks a lot!
this is the full script: *again-not complete
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
#This creates the path for the Json and also check if it is already there.
If(!(Test-Path -Path C:\Users\$env:USERNAME\documents\Json))
{
New-Item c:\users\$env:USERNAME\documents -ItemType directory -Name Json
$path = "c:\users\$env:USERNAME\documents\Json"
}
#creating the form
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Ofir`s script"
$objForm.Size = New-Object System.Drawing.Size(480,200)
$objForm.StartPosition = "CenterScreen"
#creating the label
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(20,20)
$objLabel.Size = New-Object System.Drawing.Size(280,20)
$objLabel.Text = "Please check the relevant boxes:"
$objForm.Controls.Add($objLabel)
#This creates a checkbox called dsp.z
$objDspCheckbox = New-Object System.Windows.Forms.Checkbox
$objDspCheckbox.Location = New-Object System.Drawing.Size(20,40)
$objDspCheckbox.Size = New-Object System.Drawing.Size(280,20)
$objDspCheckbox.Text = "dsp.z"
$objDspCheckbox.TabIndex = 0
$objForm.Controls.Add($objDspCheckbox)
#This creates a checkbox called fpga.bin
$objFpgaCheckbox = New-Object System.Windows.Forms.Checkbox
$objFpgaCheckbox.Location = New-Object System.Drawing.Size(20,60)
$objFpgaCheckbox.Size = New-Object System.Drawing.Size(280,20)
$objFpgaCheckbox.Text = "fpga.bin"
$objFpgaCheckbox.TabIndex = 1
$objForm.Controls.Add($objFpgaCheckbox)
#This creates a checkbox called bootrom_uncmp.bin
$objBootCheckbox = New-Object System.Windows.Forms.Checkbox
$objBootCheckbox.Location = New-Object System.Drawing.Size(20,80)
$objBootCheckbox.Size = New-Object System.Drawing.Size(280,20)
$objBootCheckbox.Text = "bootrom_uncmp.bin"
$objBootCheckbox.TabIndex = 2
$objForm.Controls.Add($objBootCheckbox)
#This creates a label for the TextBox1
$objLabel1 = New-Object System.Windows.Forms.Label
$objLabel1.Location = New-Object System.Drawing.Size(300,20)
$objLabel1.Size = New-Object System.Drawing.Size(280,20)
$objLabel1.Text = "Change the name?:"
$objForm.Controls.Add($objLabel1)
#This creates the TextBox1
$objTextBox1 = New-Object System.Windows.Forms.TextBox
$objTextBox1.Location = New-Object System.Drawing.Size(200,40)
$objTextBox1.Size = New-Object System.Drawing.Size(200,20)
$objTextBox1.TabIndex = 3
$objForm.Controls.Add($objTextBox1)
#ok Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(40,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click(
{
if ($objDspCheckbox.Checked -eq $true)
{
New-Item $path -itemtype file -name Dsp.json -value #"
"{"sys_ver":"01.01.01.02","RED":[],"RED_VA":[],"BLACK": [{"type":"6","type_descr":"DSP file","tar_name":"dsp.tar.gz","image_name":"dsp.z","CRC":"1234567","version":"01.01.01.02","metadata":"62056"}
],"BLACK_VA":[]
}"
"# ;$objForm.close()
}
elseif ($objFpgaCheckbox.Checked -eq $true)
{
New-Item $path -itemtype file -name Fpga.json -value #"
"
{"type":"4","type_descr":"FPGA file","tar_name":"FPGA.tar.gz","image_name":"fpga.z","CRC":"1234567","version":"01.01.01.02","metadata":"9730652"},
"
"#
;$objForm.close()
}
elseif ($objBootCheckbox.Checked -eq $true)
{
New-Item $path -itemtype file -name Boot.json -value "Hello3" ;$objForm.close()
}
})
$objForm.Controls.Add($OKButton)
#cancle Button
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(140,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)
#Parameters (Need to add)
$dspname = $objTextBox1
#makes the form appear on top of the screen
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
the problem is the text box is cut in the middle and only if you write a lot you will see the end of your text. please help! thanks a lot!
The problem is that the TextBox control is hidden underneath your CheckBox controls, because you've configured them to be ridiculously wide.
Change:
$objDspCheckbox.Size = New-Object System.Drawing.Size(280,20)
to something more sensible, like 150px instead of 280px:
$objDspCheckbox.Size = New-Object System.Drawing.Size(150,20)
Do this for all the checkboxes and you'll find the problem goes away.
Alternatively, bring the $objTextBox1 control to the front by setting a ChildIndex of 0 on it's parent (the Form object itself):
$objForm.Controls.SetChildIndex($objTextBox1,0)
after adding all child controls (but before calling $objForm.ShowDialog())