2012-02-06 4 views
7

私はしかし、私はそうPowerShell ISE ScriptBlockクロージャで新しいタブの作成を自動化する方法は?

$v = "hello world" 
Start-NewTab "Test" { $v } 
のようにそれを実行したときに、このような

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

としての機能の使用を開始しましたPowerShellのISE

のタブの束の作成を自動化しようとしています

hello worldは、以下の断片とは異なり、図示されていない。

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

ここでは何が起こっていて、どうやって解決するのですか?

答えて

1

"タブ"コンテナは、ISEのランスペース(またはpowershell execution environment)と同じです。新しいTab(つまり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. 

あなたの問題の1つの回避策はスクリプトブロックであなたの変数を定義することです:

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

編集:もう一つ、あなたのタイトルは「閉鎖」を言及しています。 PowershellのScriptblockはクロージャではありませんが、スクリプトブロックからクロージャを作成することはできます。しかし、これはあなたが説明する問題であなたを助けません。

EDIT2:別の回避策:

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

私がスクリプトブロックに必要なデータを作成することができれば、このヘルプは、私は変数 –

+0

を使用する必要はありませんどのように私はよく分かりませんあなたの特定の問題の制限はありますが、私は別の回避策で投稿を更新しました。 –

0

それとも単に最初のスクリプトブロックを作成します。

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

しかし、あなたは念頭に置いておく必要があります。

+0

これはどのように役立ちますか? –

+0

彼の機能は有効です。彼が行う必要があるのは、正しいオブジェクトを渡すことだけです。すべて私は彼が正しい値を渡すと、Start-NewTabが働くことを示していました。しかし、ここでの本当の問題は、最初は現在のPowerShellセッションの変数からスクリプトブロックを作成することだと思います。 –

+0

@ScottWeinsteinスクリプトブロックの作成は、最初に機能します。間違いなく範囲の問題のように見えます。変数vは、スクリプトブロック外で定義されている場合、関数内ではnullです。 –

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 } 
関連する問題