PowerShell ISE如何使用ScriptBlock闭包自动创建新的选项卡?

Sco*_*ein 7 powershell powershell-ise powershell-2.0

我正在尝试在PowerShell ISE中自动创建一组标签

我开始使用诸如此类的功能

function Start-NewTab($name, [ScriptBlock]$scriptBlock)
{
    $tab = $psISE.PowerShellTabs.Add()
    $tab.DisplayName = $name
    sleep 2
    $tab.Invoke($scriptBlock)
}
Run Code Online (Sandbox Code Playgroud)

但是,当我像这样运行它

$v = "hello world"
Start-NewTab "Test" { $v }
Run Code Online (Sandbox Code Playgroud)

hello world 没有显示,不像以下的fragement

function Test-ScriptBlock([ScriptBlock]$sb) { & $sb }
Test-ScriptBlock { $v }
Run Code Online (Sandbox Code Playgroud)

这里发生了什么,我该如何解决?

jon*_*n Z 1

“Tab”容器相当于ISE 中的运行空间(或powershell 执行环境)。由于您正在创建一个新选项卡(即 powershell 执行环境),因此变量 v 在该执行环境中未定义。脚本块在新的执行环境中进行评估并输出 v 的值(无)。

如果您尝试通过显式提及应找到变量的范围来获取脚本块中的变量,则很容易看出 Test-Scriptblock 的情况与 Start-NewTab 的情况下变量解析有何不同。

PS>Test-ScriptBlock { get-variable v -scope 0}
Get-Variable : Cannot find a variable with name 'v'.
PS>Test-ScriptBlock { get-variable v -scope 1}
Get-Variable : Cannot find a variable with name 'v'.
PS>Test-ScriptBlock { get-variable v -scope 2} # Variable found in grandparent scope (global in the same execution environment)
Name                           Value                                                                                                                           
----                           -----                                                                                                                           
v                              hello world

PS>Start-NewTab "Test" { get-variable v -scope 0 } # global scope of new execution environment
Get-Variable : Cannot find a variable with name 'v'.
PS>Start-NewTab "Test" { get-variable v -scope 1 } # proof that scope 0 = global scope
Get-Variable : The scope number '1' exceeds the number of active scopes.
Run Code Online (Sandbox Code Playgroud)

解决您的问题的一种方法是在脚本块中定义变量:

Start-NewTab "Test" { $v = "hello world";$v }
Run Code Online (Sandbox Code Playgroud)

编辑:还有一件事,你的标题提到“关闭”。Powershell 中的脚本块不是闭包,但是您可以从脚本块创建闭包。但这不会帮助您解决您所描述的问题。

编辑2:另一种解决方法:

$v = "hello world"
Invoke-Expression "`$script = { '$v' }"
Start-NewTab "test" $script
Run Code Online (Sandbox Code Playgroud)