【发布时间】:2015-11-22 12:34:36
【问题描述】:
我有一个构建脚本(Windows 2012 R2 上的 PowerShell 4),它在后台作业中运行 NUnit 并返回 NUnit 的输出。此输出收集在 Collections.Generic.List[string] 中。
$nunitJob = Start-Job -ScriptBlock {
param(
[string]
$BinRoot,
[string]
$NUnitConsolePath,
[string[]]
$NUnitParams,
[string]
$Verbose
)
Set-Location -Path $BinRoot
$VerbosePreference = $Verbose
Write-Verbose -Message ('{0} {1}' -f $NUnitConsolePath,($NUnitParams -join ' '))
& $NUnitConsolePath $NUnitParams 2>&1
$LASTEXITCODE
} -ArgumentList $binRoot,$nunitConsolePath,$nunitParams,$VerbosePreference
$nunitJob | Wait-Job -Timeout ($timeoutMinutes * 60) | Out-Null
$jobKilled = $false
if( $nunitJob.JobStateInfo.State -eq [Management.Automation.JobState]::Running )
{
$jobKilled = $true
$errMsg = 'Killing {0} tests: exceeded {1} minute timeout.' -f $assembly.Name,$timeoutMinutes
Write-Error -Message $errMsg
}
$output = New-Object 'Collections.Generic.List[string]'
$nunitJob |
Stop-Job -PassThru |
Receive-Job |
ForEach-Object {
if( -not $_ )
{
[void]$output.Add( '' )
return
}
switch -Regex ( $_ )
{
'^Tests run: (\d+), Errors: (\d+), Failures: (\d+), Inconclusive: (\d+), Time: ([\d\.]+) seconds$'
{
$testsRun = $Matches[1]
$errors = $Matches[2]
$failures = $Matches[3]
$inconclusive = $Matches[4]
$duration = New-Object 'TimeSpan' 0,0,$Matches[5]
break
}
'^ Not run: (\d+), Invalid: (\d+), Ignored: (\d+), Skipped: (\d+)$'
{
$notRun = $Matches[1]
$invalid = $Matches[2]
$ignored = $Matches[3]
$skipped = $Matches[4]
break
}
}
# Error happens here:
[void] $output.Add( $_ )
}
有时,我们的构建会因以下错误而失败:
找不到“Add”的重载和参数计数:“1”。
在行:XXXXX 字符:XXXXX
+ [无效] $output.Add( $_ )
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodCountCouldNotFindBest
知道为什么 PowerShell 找不到 List[string] 的 Add 方法吗?
我打开了一个控制台窗口,尝试将不同类型的对象传递给Add,而没有出现错误。
> $o = New-Object 'Collections.Generic.List[string]'
> $o.Add( '' )
> $o.Add( $null )
> $o.Add( 1 )
> $o
1
【问题讨论】:
-
问题很可能是它无法将
$_隐式转换为字符串。喜欢$o.Add($(New-Object psobject)) -
@zespri 我确实删除了一些行,但没有涉及
$output。 -
@MathiasR.Jessen 可能就是这样。我尝试了
$output.Add( [pscustomobject]@{ } )并且能够重现该错误。现在我必须弄清楚为什么 PowerShell 不将控制台输出视为字符串。 -
“将控制台输出视为字符串”?您是否尝试在 foreach-object 期间以任何方式修改
$_?同样,整个代码块在这里可能有用/有意义。 -
可能值得添加
Write-Verbose $_.GetType().Fullname -Verbose以查看您正在处理的对象类型。
标签: powershell