Я пытаюсь пройти через процессы, используя get-process, а затем создать кнопку для каждого процесса. Эта кнопка, on_click, удалит процесс или прямо сейчас отобразит текст. К сожалению, событие add_click отображает текст только для последнего процесса, как будто оно не прикрепляет это событие к кнопке на этой итерации.

$width = 500
$dynamicFormHeight = 100
$buttonHeight = 23
$buttonWidth = 100

function GenerateForm {

    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
    [void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
    # System.Windows.Forms.ScrollableControl.SetScrollState(int, $true) 

    foreach ($process in (Get-Process)) {
        $processLabel = New-Object System.Windows.Forms.Label
        $processLabel.Location = New-Object System.Drawing.Size((($width / 2) - ($buttonWidth/2)), ($dynamicFormHeight - 20))
        $processLabel.Size = New-Object System.Drawing.Size($buttonWidth, $buttonHeight)
        $processLabel.Text = $process.ProcessName
        $inputform.Controls.Add($processLabel)

        $dynamicFormHeight += $buttonHeight
        $Button = New-Object System.Windows.Forms.Button
        $Button.Location = New-Object System.Drawing.Size((($width / 2) + ($buttonWidth/2)), ($dynamicFormHeight - 20))
        $Button.Size = New-Object System.Drawing.Size($buttonWidth, $buttonHeight)
        $Button.Text = $process.ProcessName
        #$inputform.Controls.Add($Button)

        # -----PROBLEM AREA----------------
        $Button.Add_Click({
            Write-Host $Button.Text
        })
        $inputform.Controls.Add($Button)
        # -----PROBLEM AREA END----------------
    }

    
    $inputform.Size = New-Object System.Drawing.Size($width, $dynamicFormHeight)
    $inputform.StartPosition = "CenterScreen"
    $inputform.Add_Shown({$inputform.Activate()})
    [void] $inputform.ShowDialog()

}
GenerateForm
0
Daikyu 2 Фев 2022 в 16:13
1
Похоже, что вы зависите от захвата $Button в замыкании при передаче блока скрипта в Add_Click, а также кажется, что PowerShell не создает автоматически подобные замыкания. См. devblogs.microsoft.com/scripting/closures-in-powershell.
 – 
adv12
2 Фев 2022 в 16:44
Это также может помочь: devblogs.microsoft.com/powershell/…
 – 
adv12
2 Фев 2022 в 17:01
Почему вы дважды добавляете кнопку в элементы управления формой?
 – 
Theo
2 Фев 2022 в 17:02
Играю с позицией, потому что, хотя @adv12 дал несколько статей и сузил масштаб моей проблемы, у меня все еще есть проблема с масштабом, без каламбура.
 – 
Daikyu
2 Фев 2022 в 17:11
1
Adv12 подходит, попробуйте изменить на $Button.Add_Click({Write-Host $Button.Text}.GetNewClosure()) или $Button.Add_Click({Write-Host $this.Text})
 – 
Mathias R. Jessen
2 Фев 2022 в 17:13

2 ответа

Вы должны добавить .GetNewClosure() в конец метода .Add_Click().

Как это:

# -----PROBLEM AREA----------------
$Button.Add_Click({
    Write-Host $Button.Text
}.GetNewClosure())

$inputform.Controls.Add($Button)
# -----PROBLEM AREA END----------------

В Stack Overflow уже есть аналогичный вопрос: Похожий вопрос

0
DarkCode666 2 Фев 2022 в 17:12

Как указал DarkCode666, вы можете использовать метод GetNewClosure() для создания замыкания и области действия, но, исходя из очень фундаментального фона javascript, переменная $this кажется мне более интуитивно понятной. @Mathias R. Jessen указал на оба

$Button = New-Object System.Windows.Forms.Button

$Button.Add_Click({
    Write-Host $this.Text
})
0
Daikyu 2 Фев 2022 в 17:20