Glowie
Glowie

Reputation: 2309

PowerShell no longer reads input from textbox

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

UPDATE

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

Answers (2)

Mathias R. Jessen
Mathias R. Jessen

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

Tony Hinkle
Tony Hinkle

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

Related Questions