I guess this is a newbie question. Yet I did not find anything online...
I'm creating a small powershell script with a very simple gui.
This is the relevant part of the script:
foreach ($script in $scripts){
$btn = New-Object System.Windows.Forms.Button
#Text, Location, Size omitted
#Add clickhandler
$btn.Add_Click(
{
Write-Host "Clicked on Btn $script"
Start-Process -FilePath "powershell" -ArgumentList "-command", "`"$script`""
Write-Host "finished"
$Form.Close();
}
)
$Form.Controls.Add($btn)
}
Obviously $scripts contains paths pointing towards other powershell scripts.
Being a Java developer I was naiv enough to suspect every click handler to be created with its own reference to a script location ($script).
But of course powershell does not evaluate $script until the handler is invoked. Thus, every button will call the last element in my array $scripts since $script will reference the last element in $scripts after the loop completes.
How can I create a click handler inside a foreach-loop based on the loop-variable itself?
Solution
Mathias R. Jessen pointed me to a working solution. .GetNewClosure() called on the handler worked.
Working Code:
foreach ($script in $scripts){
$btn = New-Object System.Windows.Forms.Button
#Text, Location, Size omitted
#Add clickhandler
$btn.Add_Click(
{
Write-Host "Clicked on Btn $script"
Start-Process -FilePath "powershell" -ArgumentList "-command", "`"$script`""
Write-Host "finished"
$Form.Close();
}.GetNewClosure()
)
$Form.Controls.Add($btn)
}
$using:script$using:vardoes neither work withWrite-HostnorStart-Process