PowerShell ISE, как автоматизировать создание новой вкладки с помощью закрытий ScriptBlock? - PullRequest
7 голосов
/ 06 февраля 2012

Я пытаюсь автоматизировать создание группы вкладок в PowerShell ISE

Я начал с такой функции, как

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

, однако, когда я запускаю ее так,

$v = "hello world"
Start-NewTab "Test" { $v }

hello world не отображается, в отличие от следующего фрагмента

function Test-ScriptBlock([ScriptBlock]$sb) { & $sb }
Test-ScriptBlock { $v }

Что здесь происходит и как мне это исправить?

Ответы [ 3 ]

1 голос
/ 06 февраля 2012

Контейнер "Tab" приравнивается к пространству выполнения (или среда выполнения powershell ) в ISE.Поскольку вы создаете новую вкладку (то есть среду выполнения 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.

Одним из способов решения вашей проблемы является определение переменной в блоке сценария:

Start-NewTab "Test" { $v = "hello world";$v }

Редактировать: Еще одна вещь, ваш заголовок упоминает «закрытие».Блоки сценариев в Powershell не являются замыканиями, однако вы можете создать замыкание из блока сценариев.Это не поможет вам решить проблему, которую вы описываете.

Edit2: Другой обходной путь:

$v = "hello world"
Invoke-Expression "`$script = { '$v' }"
Start-NewTab "test" $script
0 голосов
/ 25 марта 2015

Я знаю, что это старый вопрос, однако недавно я нашел новый способ решения этой проблемы.Это может быть кому-то полезно.

Используйте переменную среды:

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

$env:v = "hello world"
Start-NewTab "Test" { $env:v }
0 голосов
/ 06 февраля 2012

Или просто сначала создайте блок скриптов.

$v={"Hello world"}                                                                                                    
start-newtab "test" $v 

Но вы должны иметь в виду область действия.

...