为什么 $hash.key 语法在 ExpandString 方法中不起作用?



下面的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'']语法?

我使用这个方法,因为这个错误存在于v4(而不是v5)中

function render() {
    [CmdletBinding()]
    param ( [parameter(ValueFromPipeline = $true)] [string] $str)
    #buggy
    #$ExecutionContext.InvokeCommand.ExpandString($str)
    "@`"`n$str`n`"@" | iex
}

示例用法:

  '$($hash.a)' | render

ExpandStringapi并不是专门用于PowerShell脚本的,它是为C#代码添加的。这仍然是一个错误,您的示例不起作用(我认为它在V4中已经修复),但这确实意味着有一个变通方法——我建议您通用。

双引号字符串有效地(但不是字面上)调用ExpandString。因此,以下内容应该是等效的:

$ExecutionContext.InvokeCommand.ExpandString('$($hash.a)')
"$($hash.a)"

我试图将提示用户的文本存储在文本文件中。我希望能够在文本文件中包含从脚本中展开的变量。

我的设置存储在一个名为$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"时发生异常:"Object引用未设置为对象的实例。"

最后,我发现我只需要将我想要的PSCustomObject值存储在常规的旧变量中,将文本文件更改为使用这些值而不是object.properties版本,一切都很好:

$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!!!

相关内容

最新更新