I'm making winforms with powershell for the first time.
I was working hard on it. but I ran into a problem. I tried to solve it by myself, but I don't know..
When I run the below code in powershell ise, $button_click works.
In other words, it worked fine in ise.
However, after saving to the desktop, $button_click does not work when running through cmd.
# start.bat
C:\Users\User\Desktop> powershell -ExecutionPolicy Unrestricted %CD%\code.ps1
I wrote the following code:
# code.ps1
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
# form specs
$Form = New-object System.Windows.Forms.Form
$Form.Text = "Check Network Status"
$Form.Size = New-object System.Drawing.Size(700,700)
$Form.StartPosition = "CenterScreen"
$Form.FormBorderStyle = "None"
$Form.KeyPreview = $True
$Form.MaximumSize = $Form.Size
$Form.MinimumSize = $Form.Size
$Form.BackColor = "Lavender"
# form icon
$Icon = New-object system.drawing.icon ("icon.ico")
$Form.Icon = $Icon
# form image
$Image = [system.drawing.image]::FromFile("img.jpg")
$PictureBox = New-Object System.Windows.Forms.PictureBox
$PictureBox.Image = $Image
$PictureBox.Size = New-object System.Drawing.Size(700,550)
$PictureBox.SizeMode = "StretchImage"
$Form.Controls.Add($PictureBox)
# ok button
$ButtonSizeWidth = 200
$ButtonSizeHeight = 50
$Button = New-object System.Windows.Forms.Button
$Font = New-Object System.Drawing.Font("Arial",20)
$Button.Location = New-object System.Drawing.Size((350 - $ButtonSizeWidth / 2),(650 - $ButtonSizeHeight))
$Button.Size = New-object System.Drawing.Size($ButtonSizeWidth,$ButtonSizeHeight)
$Button.Text = "Okay"
$Button.BackColor = "PowderBlue"
$Button.FlatAppearance.BorderSize = 0
$Button.FlatStyle = "Flat"
$Button.Font = $Font
$Button.Add_Click($button_click)
$Form.Controls.Add($Button)
# action here
$button_click =
{
# netsh int set int admin=disable
$Form.Close()
}
$Form.Add_KeyDown({if ($_.KeyCode -eq "Enter"){& $button_click}})
$Form.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$Form.Close()}})
# modal
$Form.Topmost = $True
$Form.Add_Shown({$Form.Activate()})
[void] $Form.ShowDialog()
Obviously it works fine in powershell ise, but I want to know why it doesn't work when I save and run it.
Is there something I'm missing out on?
Related
I'm trying to make a GUI for an easy tool I need to check if a specific certificate is included in the file and Output the current and next line. This already works.
If I set the variables $INT1 and $Serial1 manually within the code it also works as intended.
e.g. $INT1=31 and $Serial1="5AA61E07726DAC13".
I always get an Error that the variable is empty when inputing the same values into the GUI and clicking OK. What am I doing wrong?
The code:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objForm = New-Object System.Windows.Forms.Form
$objForm.StartPosition = "CenterScreen"
$objForm.Size = New-Object System.Drawing.Size(400,250)
$objForm.Topmost = $True
#Label+Textbox first question
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,30)
$objLabel.Size = New-Object System.Drawing.Size(800,20)
$objLabel.Text = "INT of certificate"
$objForm.Controls.Add($objLabel)
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(10,50)
$objTextBox.Size = New-Object System.Drawing.Size(200,20)
$objForm.Controls.Add($objTextBox)
#Label+Textbox second question
$objLabel2 = New-Object System.Windows.Forms.Label
$objLabel2.Location = New-Object System.Drawing.Size(10,130)
$objLabel2.Size = New-Object System.Drawing.Size(800,20)
$objLabel2.Text = "Serialnumber of the certificate"
$objForm.Controls.Add($objLabel2)
$objTextBox2 = New-Object System.Windows.Forms.TextBox
$objTextBox2.Location = New-Object System.Drawing.Size(10,150)
$objTextBox2.Size = New-Object System.Drawing.Size(200,20)
$objForm.Controls.Add($objTextBox2)
$INT1 = $objTextBox.Text;
$Serial1 = $objTextBox2.Text;
#OK Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(100,175)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Name = "OK"
#$OKButton.DialogResult = "OK"
$OKButton.Add_Click({Invoke-WebRequest -Uri http://CENSORED.crl -OutFile crl.crl;
$test=certutil.exe -dump crl.crl |Out-String -stream | Select-String -pattern "$Serial1" -Context 0,1
[void] [Windows.Forms.MessageBox]::Show($test)})
$objForm.Controls.Add($OKButton)
[void] $objForm.ShowDialog()
Thank you!
Here's a rewrite of your code.
I'm assuming that you want variables $INT1 and $Serial1 to be available after the windows closes.
In that case, fill them inside the Click() scriptblock and refer to them using $script: scoping, otherwise they are just new variables local to the scriptblock.
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# these variables need to visible inside the Click scriptblock of the button
# and be also available after the windows closes
$INT1 = $null
$Serial1 = $null
$objForm = New-Object System.Windows.Forms.Form
$objForm.StartPosition = "CenterScreen"
$objForm.Size = New-Object System.Drawing.Size(400,250)
$objForm.Topmost = $True
#Label+Textbox first question
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,30)
$objLabel.Size = New-Object System.Drawing.Size(800,20)
$objLabel.Text = "INT of certificate"
$objForm.Controls.Add($objLabel)
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(10,50)
$objTextBox.Size = New-Object System.Drawing.Size(200,20)
$objForm.Controls.Add($objTextBox)
#Label+Textbox second question
$objLabel2 = New-Object System.Windows.Forms.Label
$objLabel2.Location = New-Object System.Drawing.Size(10,130)
$objLabel2.Size = New-Object System.Drawing.Size(800,20)
$objLabel2.Text = "Serialnumber of the certificate"
$objForm.Controls.Add($objLabel2)
$objTextBox2 = New-Object System.Windows.Forms.TextBox
$objTextBox2.Location = New-Object System.Drawing.Size(10,150)
$objTextBox2.Size = New-Object System.Drawing.Size(200,20)
$objForm.Controls.Add($objTextBox2)
#OK Button
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(100,175)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Name = "OK"
#$OKButton.DialogResult = "OK"
$OKButton.Add_Click({
# you never seem to use variable $INT1, but if you do, refer to it as $script:INT1
# set the variables defined OUTSIDE the scriptblock using script-scoping
$script:INT1 = $objTextBox.Text
$script:Serial1 = $objTextBox2.Text
# create a full path and filename for the output of the Invoke-WebRequest call
$crlFile = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath 'crl.crl'
Invoke-WebRequest -Uri 'http://CENSORED.crl' -OutFile $crlFile
$test = certutil.exe -dump $crlFile | Out-String -Stream | Select-String -Pattern $script:Serial1 -Context 0,1
[void] [Windows.Forms.MessageBox]::Show($test)
# delete the temporary file
$crlFile | Remove-Item -Force
})
$objForm.Controls.Add($OKButton)
[void] $objForm.ShowDialog()
# clean up the form from memory'
$objForm.Dispose()
# here you can again see what is inside variables $INT1 and $Serial1
Write-Host "Last entered values: $INT1 $Serial1"
All user interaction with your form happens in this, blocking call:
[void] $objForm.ShowDialog()
See the ShowDialog() method.
Therefore, if you want to store results from that user interaction in variables, place the assignments after the call, and reference the controls of interest.
# ... form setup
# Show the form modally (as a dialog).
# The call blocks until the form is closed.
# Note:
# You may want to examine the return value in case there
# are multiple ways to close your form, and one of those ways
# signals having *canceled*, for instance.
$null = $objForm.ShowDialog()
# Now you can get values from the controls and assign them to (script) variables.
$INT1 = $objTextBox.Text
$Serial1 = $objTextBox2.Text
Note: If you need to set script-level variables - i.e., variables visible after a .ShowDialog() call - from inside script blocks serving as event delegates (e.g., the script block passed to $OKButton.Add_Click()), you need to use the $script: scope, given that such script blocks run in a child scope too - see this answer.
After selecting an option from the drop down list ($RCVROption), when choosing an option from the list provided ($listBox), the $listBox.SelectedItems values are always Null. How do I get those values to assign to variable $x
This is the script I tried, my goal is to have the text from $listBox.SelectedItems to be used as a value that represents a file name, so that when you select an option from the list, and click OK, it runs that file.
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[System.Windows.Forms.Application]::EnableVisualStyles()
$form = New-Object System.Windows.Forms.Form
$form.Text = 'DMP Receiver Tail'
$form.Size = New-Object System.Drawing.Size(400,300)
$form.StartPosition = 'CenterScreen'
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Point(115,220)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = 'OK'
$OKButton.DialogResult = [System.Windows.Forms.DialogResult]::OK
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Point(190,220)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = 'Cancel'
$CancelButton.DialogResult = [System.Windows.Forms.DialogResult]::Cancel
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Point(60,20)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.Text = 'Which Receiver Would You Like To Tail?:'
$form.Controls.Add($label)
$RCVROption = new-object System.Windows.Forms.combobox
$RCVROption.Location = new-object System.Drawing.Size(20,40)
$RCVROption.Size = new-object System.Drawing.Size(335,30)
[void] $RCVROption.Items.Add('Receiver 560')
[void] $RCVROption.Items.Add('Receiver 2560')
$RCVROption.tabIndex = '0'
$RCVROption.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList;
$RCVROption.add_SelectedValueChanged(
{
if($RCVROption.SelectedItem -eq 'Receiver 560')
{
$listBox = New-Object System.Windows.Forms.Listbox
$listBox.Location = New-Object System.Drawing.Point(40,100)
$listBox.Size = New-Object System.Drawing.Size(260,80)
$listBox.SelectionMode = 'MultiExtended'
[void] $listBox.Items.Add('DMP-560-Line1')
[void] $listBox.Items.Add('DMP-560-Line2')
[void] $listBox.Items.Add('DMP-560-Line3')
[void] $listBox.Items.Add('DMP-560-Line4')
[void] $listBox.Items.Add('DMP-560-Line5')
$form.Controls.Add($listBox)
}
ELSEIF($RCVROption.SelectedItem -eq 'Receiver 2560')
{
$listBox = New-Object System.Windows.Forms.Listbox
$listBox.Location = New-Object System.Drawing.Point(40,100)
$listBox.Size = New-Object System.Drawing.Size(260,80)
$listBox.SelectionMode = 'MultiExtended'
[void] $listBox.Items.Add('DMP-2560-Line1')
[void] $listBox.Items.Add('DMP-2560-Line2')
[void] $listBox.Items.Add('DMP-2560-Line3')
[void] $listBox.Items.Add('DMP-2560-Line4')
[void] $listBox.Items.Add('DMP-2560-Line5')
$form.Controls.Add($listBox)
}
}
)
$form.Controls.Add($RCVROption)
$form.Topmost = $true
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK)
{
$x = $listBox.SelectedItems
$Fpath = 'D:\Toolbar\On Call\DMP-Tail\' + $x + '.exe'
Start-process -filepath $FPath
$Fpath
}
Based on your code, I'm guessing you come from a C# background. PowerShell does something weird where it can normally reach outside of script block's scope {code in scriptblock} and use variables that already exist at the time the scriptblock is executed. But it can't easily create or add new variables in the parent/outer scope.
Your code is creating $listBox inside the $RCVROption.add_SelectedValueChanged({code in scriptblock}) event scriptblock, and adding it to the controls for the form, so it continues to exist in the form, but not at the global/script scope of the your code.
I've reworked your code in a format that I've been learning over the last year. Everything you had should still be there, only in a more condensed form. You don't have to use this format, but I personally really like it. How PowerShell converts things like "Cancel" into [System.Windows.Forms.DialogResult]::Cancel is a bit of a mistery to me, but this type of conversion seems very reliable.
This version of the code creates the $listBox prior to firing of the $RCVROption.add_SelectedValueChanged event, clears the items in $listBox, and then populates the ListBox with the new values. The values are in an array, and piped into the [void] $listBox.Items.Add($_) command, executing it once per item in the array.
using namespace System.Windows.Forms
using namespace System.Drawing
Set-StrictMode -Version 3.0
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[Application]::EnableVisualStyles()
$form = [Form]#{
Text = 'DMP Receiver Tail'
Size = "400,300"
StartPosition = 'CenterScreen'
Topmost = $true
}
$OKButton = [Button]#{
DialogResult = "OK"
Location = "115,220"
Size = "75,23"
Text = 'OK'
}
$form.AcceptButton = $OKButton
$form.Controls.Add($OKButton)
$CancelButton = [Button]#{
DialogResult = "Cancel"
Location = "190,220"
Size = "75,23"
Text = 'Cancel'
}
$form.CancelButton = $CancelButton
$form.Controls.Add($CancelButton)
$label = [Label]#{
Location = "60,20"
Size = "280,20"
Text = 'Which Receiver Would You Like To Tail?:'
}
$form.Controls.Add($label)
$RCVROption = [ComboBox]#{
DropDownStyle = "DropDownList"
Location = "20,40"
Size = "335,30"
tabIndex = '0'
}
[void] $RCVROption.Items.Add('Receiver 560')
[void] $RCVROption.Items.Add('Receiver 2560')
$listBox = [Listbox]#{
Location = "40,100"
SelectionMode = 'MultiExtended'
Size = "260,80"
}
$form.Controls.Add($listBox)
$RCVROption.add_SelectedValueChanged({
if($RCVROption.SelectedItem -eq 'Receiver 560') {
$listBox.Items.Clear()
'DMP-560-Line1', 'DMP-560-Line2', 'DMP-560-Line3', 'DMP-560-Line4', 'DMP-560-Line5' | ForEach-Object {
[void] $listBox.Items.Add($_)
}
}
elseif($RCVROption.SelectedItem -eq 'Receiver 2560') {
$listBox.Items.Clear()
'DMP-2560-Line1', 'DMP-2560-Line2', 'DMP-2560-Line3', 'DMP-2560-Line4', 'DMP-2560-Line5' | ForEach-Object {
[void] $listBox.Items.Add($_)
}
}
})
$form.Controls.Add($RCVROption)
$result = $form.ShowDialog()
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
$x = $listBox.SelectedItems
$Fpath = 'D:\Toolbar\On Call\DMP-Tail\' + $x + '.exe'
Start-process -filepath $FPath
$Fpath
}
I wrote six small gui scripts that I'd like to place in a single file, for the sake of converting said file into rxecutable with ps2exe.
I've found a script ,here on stack that is perfect for what I want. Unfortunatelly I cann't find any info on script placement within tabs and MS documentation leads me to ISE tabs, which is not helpfull.
Say I'd like to place this
Add-Type -AssemblyName PresentationFramework
$button_click = {
$folder = $textBox1.Text;
$pytanie = [System.Windows.MessageBox]::Show('Czy chcesz usunac folder?', '', '4');
If($pytanie -eq 'Yes')
{Remove-Item –path $folder –recurse -Force};
$test = Test-Path $folder;
if ($test -eq $false){[System.Windows.MessageBox]::Show('Folder Usuniety', '', '0')}}
$label2 = New-Object System.Windows.Forms.Label
$label2.AutoSize = $True
$label2.Text = ("Scieżka")
$label2.Location = New-Object System.Drawing.Point (10,30)
$label2.Size = New-Object System.Drawing.Size (25,70)
$label2.Font = [System.Drawing.Font]::new("Arial", 10, [System.Drawing.FontStyle]::Bold)
$textBox1 = New-Object System.Windows.Forms.TextBox
$textBox1.Location = New-Object System.Drawing.Point(10,70) ### Location of the text box
$textBox1.Size = New-Object System.Drawing.Size(200,50) ### Size of the text box
$textBox1.Multiline = $false ### Allows multiple lines of data
$textBox1.Font = New-Object System.Drawing.Font("Consolas",10,[System.Drawing.FontStyle]::Regular)
$textBox1.ReadOnly=$false
$button = New-Object System.Windows.Forms.Button
$button.Location = New-Object System.Drawing.Point(10,120)
$button.Size = New-Object System.Drawing.Size (200,30)
$button.Text = "Usun Folder"
$button.Add_Click($button_click)
$form = New-Object System.Windows.Forms.Form
$form.Text = 'Mapowanie' ### Text to be displayed in the title
$form.Size = New-Object System.Drawing.Size(240,200) ### Size of the window
$form.StartPosition = 'Manual'
$form.Location = '10,10'
$form.Topmost = $true ### Optional - Opens on top of other windows
$form.Controls.AddRange(#($textBox1,$button, $label2))
$form.ShowDialog()
within a tab. How to do it?
I think that it the
$Tab1.Controls.Add($button)
You are looking for.
For example
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$ApplicationForm = New-Object System.Windows.Forms.Form
$ApplicationForm.StartPosition = "CenterScreen"
$ApplicationForm.Topmost = $false
$ApplicationForm.Size = "800,600"
$FormTabControl = New-object System.Windows.Forms.TabControl
$FormTabControl.Size = "755,475"
$FormTabControl.Location = "25,75"
$ApplicationForm.Controls.Add($FormTabControl)
$Tab1 = New-object System.Windows.Forms.Tabpage
$Tab1.DataBindings.DefaultDataSourceUpdateMode = 0
$Tab1.UseVisualStyleBackColor = $True
$Tab1.Name = "Tab1"
$Tab1.Text = "Tab1”
$FormTabControl.Controls.Add($Tab1)
$textBox1 = New-Object System.Windows.Forms.TextBox
$textBox1.Location = New-Object System.Drawing.Point(10,70) ### Location of the text box
$textBox1.Size = New-Object System.Drawing.Size(200,50) ### Size of the text box
$textBox1.Multiline = $false ### Allows multiple lines of data
$textBox1.Font = New-Object System.Drawing.Font("Consolas",10,[System.Drawing.FontStyle]::Regular)
$textBox1.ReadOnly=$false
$Tab1.Controls.Add($textBox1)
$Tab2 = New-object System.Windows.Forms.Tabpage
$Tab2.DataBindings.DefaultDataSourceUpdateMode = 0
$Tab2.UseVisualStyleBackColor = $True
$Tab2.Name = "Tab2"
$Tab2.Text = "Tab2”
$FormTabControl.Controls.Add($Tab2)
$button = New-Object System.Windows.Forms.Button
$button.Location = New-Object System.Drawing.Point(10,120)
$button.Size = New-Object System.Drawing.Size (200,30)
$button.Text = "Usun Folder"
$button.Add_Click($button_click)
$Tab2.Controls.Add($button)
# Initlize the form
$ApplicationForm.Add_Shown({$ApplicationForm.Activate()})
[void] $ApplicationForm.ShowDialog()
I'm very rusty in the area of powershell and trying to pick it back up but I have something bothering me that I can't seem to figure out. I've created a form that has two text inputs for file locations and a drop down list. What I'm attempting to do is compare the two files received in a text input. I've got the script already for the compare but what I'm trying to figure out is how I distinguish the script to be run from the selection of the drop down list and also parse the two text inputs from the form to the relevant compare script. Below is the generic form created. Any help would be much appreciated.
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(700,700)
#You can use the below method as well
#$Form.Width = 400
#$Form.Height = 200
$form.MaximizeBox = $false
$Form.StartPosition = "CenterScreen"
$Form.FormBorderStyle = 'Fixed3D'
$Form.Text = "IAM Application Comparison Tool"
#application Drop down list
$Label = New-Object System.Windows.Forms.Label
$Label.Text = "Please select the application being compared"
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(10,10)
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$form.Font = $Font
$Form.Controls.Add($Label)
#list of applications
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,50)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80
[void] $listBox.Items.Add('Terradata')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
[void] $listBox.Items.Add('')
$form.Controls.Add($listBox)
#File path of previous months file
$Label = New-Object System.Windows.Forms.Label
$Label.Text = "Enter file path of previous months file"
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(20,200)
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$form.Font = $Font
$Form.Controls.Add($Label)
#Input file path
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(20,300)
$textBox.Size = New-Object System.Drawing.Size(450,20)
$form.Controls.Add($textBox)
#$formIcon = New-Object system.drawing.icon ("$env:USERPROFILE\desktop\Blog\v.ico")
#$form.Icon = $formicon
#File path of current month
$Label = New-Object System.Windows.Forms.Label
$Label.Text = "Enter file path of current months file"
$Label.AutoSize = $true
$Label.Location = New-Object System.Drawing.Size(20,400)
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$form.Font = $Font
$Form.Controls.Add($Label)
#Input file path
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(20,500)
$textBox.Size = New-Object System.Drawing.Size(450,20)
$form.Controls.Add($textBox)
#Run Required Compare script
$Okbutton = New-Object System.Windows.Forms.Button
$Okbutton.Location = New-Object System.Drawing.Size(170,600)
$Okbutton.Size = New-Object System.Drawing.Size(200,30)
$Okbutton.Text = "Compare Files"
$Okbutton.Add_Click()
$Form.Controls.Add($Okbutton)
$Form.ShowDialog()
Create a function that will run whenever the button is clicked.
for instance, your button event will be:
$Okbutton.Add_Click({ BtnClick })
then add the function that will do the compare, whenever the button is clicked the function will be called:
function BtnClick{
# do something / compare your texts
#compare $TextBox1.Text $TextBox2.Text
}
you have to give a different variable name for each textbox, this how you'll be able to access the values:
$input1 = $TextBox1.Text
$input2 = $TextBox2.Text
$input3 = $ComboBox1.Text
The easiest way to have your code distinguish between the different objects is to name them upon creation, so use different variable names for the textboxes and the like.
To act on the button click, you already started by writing $Okbutton.Add_Click(), but since there is no scriptblock to actually do something there, nothing would happen.
The listbox can also react on an event, in this case that would be the SelectedIndexChanged event.
Please see the revised code below that shows how to implement these event handlers
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
[void] [System.Windows.Forms.Application]::EnableVisualStyles()
$Form = New-Object system.Windows.Forms.Form
$Form.Size = New-Object System.Drawing.Size(700,700)
$Form.MaximizeBox = $false
$Form.StartPosition = "CenterScreen"
$Form.FormBorderStyle = 'Fixed3D'
$Form.Text = "IAM Application Comparison Tool"
$Font = New-Object System.Drawing.Font("Arial",15,[System.Drawing.FontStyle]::Bold)
$Form.Font = $Font
#application Drop down list
$LabelDropDown = New-Object System.Windows.Forms.Label
$LabelDropDown.Text = "Please select the application being compared"
$LabelDropDown.AutoSize = $true
$LabelDropDown.Location = New-Object System.Drawing.Size(10,10)
$Form.Controls.Add($LabelDropDown)
# list of applications
$listBox = New-Object System.Windows.Forms.ListBox
$listBox.Location = New-Object System.Drawing.Point(10,50)
$listBox.Size = New-Object System.Drawing.Size(260,20)
$listBox.Height = 80
# add the items to the listbox
$null = $listBox.Items.AddRange(#('Terradata','SomeApp','MyApp','ThirdPartyApp'))
# set the current selected item to be the first
$listBox.SelectedIndex = 0
# add functionality to react on index changed
$listBox.Add_SelectedIndexChanged({
# do something when the user chose a different app in the listbox
# for demo, just write the currently selected item in the console
Write-Host "Currently selected app in the listbox: $($this.SelectedItem)"
})
$Form.Controls.Add($listBox)
# File path of previous months file
$LabelPrevious = New-Object System.Windows.Forms.Label
$LabelPrevious.Text = "Enter file path of previous months file"
$LabelPrevious.AutoSize = $true
$LabelPrevious.Location = New-Object System.Drawing.Size(20,200)
$Form.Controls.Add($LabelPrevious)
# first Input file path
$textBoxFile1 = New-Object System.Windows.Forms.TextBox
$textBoxFile1.Location = New-Object System.Drawing.Point(20,300)
$textBoxFile1.Size = New-Object System.Drawing.Size(450,20)
$Form.Controls.Add($textBoxFile1)
# File path of current month
$LabelCurrent = New-Object System.Windows.Forms.Label
$LabelCurrent.Text = "Enter file path of current months file"
$LabelCurrent.AutoSize = $true
$LabelCurrent.Location = New-Object System.Drawing.Size(20,400)
$Form.Controls.Add($LabelCurrent)
# second Input file path
$textBoxFile2 = New-Object System.Windows.Forms.TextBox
$textBoxFile2.Location = New-Object System.Drawing.Point(20,500)
$textBoxFile2.Size = New-Object System.Drawing.Size(450,20)
$Form.Controls.Add($textBoxFile2)
# Run Required Compare script
$Okbutton = New-Object System.Windows.Forms.Button
$Okbutton.Location = New-Object System.Drawing.Size(170,600)
$Okbutton.Size = New-Object System.Drawing.Size(200,30)
$Okbutton.Text = "Compare Files"
# add functionality for comparing files
$Okbutton.Add_Click({
# your compare function comparing the file in $textbox1 against the file in $textbox2
# IF both fields contain a valid file path and name of course ;)
# for demo just output in console
Write-Host "Compare file '$($textBoxFile1.Text)' to '$($textBoxFile2.Text)'"
})
$Form.Controls.Add($Okbutton)
$Form.ShowDialog()
# important! dispose of the form when done
$Form.Dispose()
P.S. Inside the scriptblocks for the Click and the SelectedIndexChanged events, you can use automatic variable $this, which refers to the current form control object.
I have some ps script which is runs OK via PowerShell ISE env.
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Data Entry Form"
$objForm.Size = New-Object System.Drawing.Size(600,400)
$objForm.StartPosition = "CenterScreen"
$objTextBox = New-Object System.Windows.Forms.TextBox
$objTextBox.Location = New-Object System.Drawing.Size(50,50)
$objTextBox.Size = New-Object System.Drawing.Size(150,20)
$findLabel = New-Object System.Windows.Forms.Label
$findLabel.Location = New-Object System.Drawing.Size(50,100)
$findLabel.Size = New-Object System.Drawing.Size(300,20)
$findLabel.Text = "Nađi:"
$findBox = New-Object System.Windows.Forms.TextBox
$findBox.Location = New-Object System.Drawing.Size(50,120)
$findBox.Size = New-Object System.Drawing.Size(260,20)
$replaceLabel = New-Object System.Windows.Forms.Label
$replaceLabel.Location = New-Object System.Drawing.Size(50,180)
$replaceLabel.Size = New-Object System.Drawing.Size(300,20)
$replaceLabel.Text = "Zameni sa:"
$replaceBox = New-Object System.Windows.Forms.TextBox
$replaceBox.Location = New-Object System.Drawing.Size(50,200)
$replaceBox.Size = New-Object System.Drawing.Size(260,20)
$objForm.Controls.Add($startButton)
$objForm.Controls.Add($findBox)
$objForm.Controls.Add($replaceBox)
$objForm.Controls.Add($objTextBox)
$objForm.Controls.Add($beginScriptButton)
$objForm.Controls.Add($findLabel)
$objForm.Controls.Add($replaceLabel)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
$startButton = New-Object System.Windows.Forms.Button
$startButton.Location = New-Object System.Drawing.Size(220,50)
$startButton.Size = New-Object System.Drawing.Size(75,23)
$startButton.Text = "Browse!"
$startButton.Add_Click({
$browser = New-Object System.Windows.Forms.FolderBrowserDialog
$browser.Location = New-Object System.Drawing.Size(60,60)
$null = $browser.ShowDialog()
$path = $browser.SelectedPath
$objTextBox.Text = $path
})
$beginScriptButton = New-Object System.Windows.Forms.Button
$beginScriptButton.Location = New-Object System.Drawing.Size(350,130)
$beginScriptButton.Size = New-Object System.Drawing.Size(350,180)
$beginScriptButton.Text = "Begin"
$beginScriptButton.Add_Click({
$a = $objTextBox.Text
if(($a) -and ($findBox.Text) -and ($replaceBox.Text)){
$objWord = New-Object -comobject Word.Application
$objWord.Visible = $false
$list = Get-ChildItem "c:\users\stefan\test\*.*" -Include *.doc*
foreach($item in $list){
$objDoc = $objWord.Documents.Open($item.FullName,$true)
$objSelection = $objWord.Selection
$wdFindContinue = 1
$FindText = $findBox.Text
$MatchCase = $false
$MatchWholeWord = $true
$MatchWildcards = $False
$MatchSoundsLike = $False
$MatchAllWordForms = $False
$Forward = $True
$Wrap = $wdFindContinue
$Format = $False
$wdReplaceNone = 0
$ReplaceWith = $replaceBox.Text
$wdFindContinue = 1
$ReplaceAll = 2
$a = $objSelection.Find.Execute($FindText,$MatchCase,$MatchWholeWord, `
$MatchWildcards,$MatchSoundsLike,$MatchAllWordForms,$Forward,`
$Wrap,$Format,$ReplaceWith,$ReplaceAll)
$objDoc.Save()
$objDoc.Close()
}
$objWord.Quit()
[System.Windows.Forms.MessageBox]::Show("Uspešno ste izvršili izmenu!")
}
else{
[System.Windows.Forms.MessageBox]::Show("Please fill in all fields.")
}
})
Then, I compile it via PowerGUI as .exe
And I run it, first, it opens a cmd and after a second it disappear, I can't even see my powershell form that I've created through the code.
I've tried different options through PowerGui (I want to not be displayed a cmd window, just my form). Do you know some way how to compile it to .exe and to see only form and logic behind it?
Thanks!
Compiling the script as an exe in Powershell runs it in a new instance, where you'll need to load the form components. Try adding this to the start of your script:
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")