Powershell V2与V4范围差异

时间:2015-06-29 18:51:02

标签: scope powershell-v2.0 powershell-v4.0

我对这方面的文献很难。我希望有人可以解释这里的差异,以便我能更好地理解我的脚本流程。

function select-bin {
    $objForm = New-Object System.Windows.Forms.Form 
    $objForm.Text = "Select a Bin"
    $objForm.Size = New-Object System.Drawing.Size(300,200) 
    $objForm.StartPosition = "CenterScreen"

    $x = @()

    # Create $OKButton and $objListBox ... removed code as not relevant.

    $OKButton.Add_Click({
        $x+=$objListBox.SelectedItems
        $objForm.Close()
    })

    $objForm.ShowDialog()
    if ($x) {
        return $x
    }
    else {
        return $null
    }
}

在上面的代码示例中,它在Powershell V2中运行良好,但在V4中,add_click部分不起作用。它成功关闭了表单(在函数范围中创建)但无法更新$ x。

所以我想这是我的问题。

  1. 在V2中,add_click部分是否与函数在同一范围内考虑? (只有这样我才能看到它能够更新$ x)
  2. 让这样的事件改变数据的正确方法是什么?我觉得在全局范围内声明$ x有点多见,因为我只需要它在函数中。
  3. 在V4中,add_click的运行范围是什么?它明显不同于V2,但它是否在全球范围内运行?它是相对于$ OKButton还是函数?我假设它是全球或功能的孩子,但我真的不知道。
  4. 任何人都可以提供的任何清晰度都将不胜感激。在我的公司迁移到V4之前,我有很多要做的更新,因为我没有遵循范围界定的最佳实践(我的不好)。

1 个答案:

答案 0 :(得分:1)

在V2中,ScriptBlock在转换为委托时,会在任何恰好是当前作用域的范围内运行源点。

通常,这是创建脚本块的范围,所以事情自然而然。但在某些情况下,它所运行的范围与其创建的范围无关。

在V4中,这些脚本块在它们自己的作用域中运行 - 一个新作用域,它是当前作用域的子作用域,就像它们是一个函数一样,你通常调用函数(不是点源)。

我认为你最好的选择是使用以下之一(大致最好到最差):

  • $脚本:X
  • $ x = Get-Variable -Scope 1 -Name x
  • $全球:X