Reputation: 2309
Last time I ran this script was 2 years ago, and I thought maybe I'm not transferring $userInput
back to main program, but even the function doesn't read $userInput
.
How to troubleshoot?
function getValues($formTitle, $textTitle){
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = $formTitle
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter") {$x=$objTextBox.Text;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape") {$objForm.Close()}})
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$userInput=$objTextBox.Text;$objForm.Close()})
$objForm.Controls.Add($OKButton)
$CANCELButton = New-Object System.Windows.Forms.Button
$CANCELButton.Location = New-Object System.Drawing.Size(150,120)
$CANCELButton.Size = New-Object System.Drawing.Size(75,23)
$CANCELButton.Text = "CANCEL"
$CANCELButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CANCELButton)
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(280,30)
$objLabel.Text = $textTitle
$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(260,20)
$objForm.Controls.Add($objTextBox)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
write-host user Input is $userInput
return $userInput
}
$schema = getValues "Database Schema" "Enter database schema"
$db_IP = getValues "Database Server" "Enter IP address where database is located"
$init_cat = getValues "Database Name" "Enter database name "
$userID = getValues "Database Administrator Username" "Enter username of database administrator"
Output is
user Input is
user Input is
user Input is
user Input is
When I try code from https://technet.microsoft.com/en-us/library/ff730941.aspx and add write-host $x
, there is no output
PowerShell version 4.0
Upvotes: 1
Views: 1226
Reputation: 174445
Last time I ran this script was 2 years ago
As of PowerShell version 3.0, the scope of the delegate invoked by an event handler such as
$OKButton.Add_Click({$userInput=$objTextBox.Text;$objForm.Close()})
is distinct from the containing script, meaning that when you assign something to $userInput
inside the Add_Click
scriptblock, you're actually assigning something to a variable that is local to that scriptblock.
The fix is to explicitly state a parent-scope, like this:
$OKButton.Add_Click({$Script:userInput=$objTextBox.Text;$objForm.Close()})
It's the same behavior that causes the TechNet example to not run correctly in PowerShell 4.0 - unless you substitute all inline mentions of $x
with $Script:x
or $Global:x
You can read more about the dynamic scoping model in PowerShell (and how variables initialized in a child scope may end up hiding variables sharing their name in a parent scope) in the about_Scopes
helpfile:
Get-Help about_Scopes -Full
Upvotes: 3
Reputation: 4742
I've never done anything with forms before, but making the $userInput assignment to $objTextBox.Text after the ShowDialog() worked for me:
[void] $objForm.ShowDialog()
$userInput = $objTextBox.Text
write-host user Input is $userInput
Upvotes: 1