2012-02-06 3 views
7

Я пытаюсь автоматизировать создание кучу вкладок в PowerShell ISEPowerShell ISE как автоматизировать создание новых вкладок с закрытием ScriptBlock?

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

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 } 

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

ответ

1

Контейнер «Tab» приравнивается к пробелу (или powershell execution environment) в 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. 

Один из способов для вашей проблемы, чтобы определить переменную в ScriptBlock:

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

Edit: Еще одна вещь, ваше название упоминает 'закрытие'. Scriptblocks в Powershell не являются закрытием, однако вы можете создать закрытие из скриптового блока. Однако это не поможет вам с проблемой, которую вы описываете.

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

$v = "hello world" 
Invoke-Expression "`$script = { '$v' }" 
Start-NewTab "test" $script 
+0

Как это поможет, если я мог бы создать необходимые данные в ScriptBlock, я не должен был бы использовать переменную –

+0

Я не уверен, что ограничения для вашей конкретной проблемы, однако я обновил свой пост с помощью другого обходного пути. –

0

Или просто создать ScriptBlock первым.

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

Но вы должны помнить об этом.

+0

Как это помогает? –

+0

Его функция действительна, все, что ему нужно сделать, это передать правильный объект. Все, что я показывал, что, если он передает правильные значения, работает Start-NewTab. Но я думаю, что настоящая проблема здесь заключается в создании скриптового блока из переменных в текущем сеансе PowerShell. –

+0

@ScottWeinstein Создание первого скриптового блока. Определенно выглядит проблема с областью. Переменная v равна нулю внутри функции, если она была определена вне скриптового блока. –

0

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

Используйте переменную окружения:

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 } 

 Смежные вопросы

  • Нет связанных вопросов^_^