8

次のPowershellスクリプトは、この問題を示しています。

$hash = @{'a' = 1; 'b' = 2}
Write-Host $hash['a']        # => 1
Write-Host $hash.a           # => 1

# Two ways of printing using quoted strings.
Write-Host "$($hash['a'])"   # => 1
Write-Host "$($hash.a)"      # => 1

# And the same two ways Expanding a single-quoted string.
$ExecutionContext.InvokeCommand.ExpandString('$($hash[''a''])') # => 1
$ExecutionContext.InvokeCommand.ExpandString('$($hash.a)')      # => Oh no!

Exception calling "ExpandString" with "1" argument(s): "Object reference not set to an instance of an object."
At line:1 char:1
+ $ExecutionContext.InvokeCommand.ExpandString('$($hash.a)')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : NullReferenceException

$hash.key構文が明示的な拡張の内部以外のどこでも機能する理由を知っている人はいますか?$hash[''key'']これを修正することはできますか、それとも構文を理解して生きる必要がありますか?

4

3 に答える 3

4

このバグは v4 に存在するため (v5 には存在しない)、この方法を使用します。

function render() {
    [CmdletBinding()]
    param ( [parameter(ValueFromPipeline = $true)] [string] $str)

    #buggy
    #$ExecutionContext.InvokeCommand.ExpandString($str)

    "@`"`n$str`n`"@" | iex
}

あなたの例の使用法:

  '$($hash.a)' | render
于 2015-03-12T09:04:55.820 に答える
1

ユーザーにプロンプ​​トを表示するテキストをテキスト ファイルに保存しようとしていました。スクリプトから展開されたテキスト ファイルに変数を含めることができるようにしたいと考えていました。

私の設定は $profile という PSCustomObject に保存されているので、私のテキストでは次のようなことをしようとしていました:

Hello $($profile.First) $($profile.Last)!!!

そして、私がやろうとしていたスクリプトから:

$profile=GetProfile #Function returns PSCustomObject 
$temp=Get-Content -Path "myFile.txt"
$myText=Join-String $temp
$myText=$ExecutionContext.InvokeCommand.ExpandString($myText) 

もちろん、エラーが発生しました

"1" 個の引数を指定して "ExpandString" を呼び出し中に例外が発生しました: "オブジェクト参照がオブジェクトのインスタンスに設定されていません。"

最後に、必要な PSCustomObject 値を通常の古い変数に保存し、テキスト ファイルを object.property バージョンの代わりにそれらを使用するように変更するだけでよいことがわかりました。すべてがうまく機能しました。

$profile=GetProfile #Function returns PSCustomObject 
$First=$profile.First
$Last=$profile.Last
$temp=Get-Content -Path "myFile.txt"
$myText=Join-String $temp
$myText=$ExecutionContext.InvokeCommand.ExpandString($myText) 

そして、私が変更したテキストで

こんにちは $First $Last!!!

于 2014-12-05T15:45:35.883 に答える
1

ExpandString API は、PowerShell スクリプトから使用するためのものではなく、C# コード用に追加されたものです。あなたの例が機能しないのはまだバグです (V4 で修正されたと思います) が、回避策があることを意味します - 一般的な使用に推奨するものです。

二重引用符文字列は、事実上 (文字どおりではなく) ExpandString を呼び出します。したがって、以下は同等である必要があります。

$ExecutionContext.InvokeCommand.ExpandString('$($hash.a)')
"$($hash.a)"
于 2013-09-23T03:09:41.723 に答える