2012-07-23 98 views
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'']語法一起生活?

+1

它實際上比這更糟糕 - 我不能得到*任何*實際的子表達式擴展使用這種語法,只有簡單的東西,如$($ foo)工作,例如'$(Get-Date | select -expand DayOfWeek)'會引發同樣的異常。建議在連接上報告它,這是突破變化/錯誤的IMO。 – BartekB 2012-07-23 11:38:00

+0

報告它在哪裏?在這種情況下,我不知道「連接」是什麼意思。 – 2012-07-23 15:49:01

+1

對不起,應該更具體......:http://connect.microsoft.com/powershell->報告這類問題的最佳地點。 – BartekB 2012-07-23 21:58:19

回答

1

ExpandString api並非完全適用於PowerShell腳本,它更多地用於C#代碼。這仍然是一個錯誤,您的示例不起作用(我認爲它已在V4中得到修復),但這確實意味着有一種解決方法 - 我推薦一種常用的解決方法。

雙引號字符串有效(但不是字面上)調用ExpandString。所以下面應該是等效的:

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

那麼你如何延遲處理雙引號字符串?這樣做的全部原因是,當定義字符串「$($ hash.a)」時不存在的變量可以在運行時嵌入到結果中。 – 2013-09-26 02:45:35

+0

雙引號字符串的處理在執行表達式時發生,而不是在被解析時發生。換句話說,如果您調用ExpandString api,處理就會發生。 – 2013-09-26 03:49:56

+0

哪個不回答問題。你將如何編碼$ str,以便這個例子寫'後'? $ hash ['a'] ='Before':$ str ='$($ hash.a)':$ hash ['a'] ='After':Write.Host $ ExecutionContext.InvokeCommand.ExpandString($ str )' – 2013-09-27 21:58:56

1

我試圖存儲在文本文件中提示用戶的文本。我希望能夠在我的腳本中擴展的文本文件中具有變量。

我的設置存儲在一個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) 

這當然給我留下誤差

異常呼叫「ExpandString」與「1」的參數(一個或多個):「對象 引用未設置爲對象的實例。「

最後我想通了,我只需要存儲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) 

而在正文中我更改爲

Hello $ First $ Last !!!

4

我用這個方法,因爲這個bug在V4(未在V5)

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

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

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

使用您的例子存在:

'$($hash.a)' | render 
相關問題