传递string []

时间:2016-01-04 14:53:42

标签: powershell tfs-sdk azure-pipelines

我有一个方法,我试图从powershell调用,它是

 Workspace.GetPendingChanges(string[] items)

这种方法有多重载荷,但那些使我的生活艰难的是:

 Workspace.GetPendingChanges(string items)
 Workspace.GetPendingChanges(string[] items)
 Workspace.GetPendingChanges(ItemSpec[] itemspecs)

我正在使用TFS 2015新构建任务中的Find-Files cmdlet获取文件列表:

if ($ItemSpec.Contains("*") -Or $ItemSpec.Contains("?"))
{
    Write-Verbose "Pattern found in solution parameter. Calling Find-Files."
    Write-Verbose "Calling Find-Files with pattern: $ItemSpec"    
    [string[]] $FilesToCheckin = @(Find-Files -SearchPattern $ItemSpec -RootFolder $env:BUILD_SOURCESDIRECTORY)
    Write-Verbose "Found files: $FilesToCheckin"
}
else
{
    Write-Verbose "No Pattern found in solution parameter."
    [string[]] $FilesToCheckin = @($ItemSpec)
}

然后我打电话给:

$pendingChanges = $provider.Workspace.GetPendingChanges( @($FilesToCheckin))

我已经尝试了任何版本的强制转换[string[]]强制数组符号@()我知道,但是find-files的结果总是转换为单个长字符串,然后才传递给正确的过载:

System.Management.Automation.MethodInvocationException: Exception calling "GetPendingChanges" with "1" argument(s): "TF400889: The following path contains more than the allowed 259 characters: 

这是生成的“长字符串”

C:\TfsData\Build\_work\1\s\BuildProcessTemplates\AzureContinuousDeployment.11.xaml C:\TfsData\Build\_work\1\s\BuildProcessTemplates\DefaultTemplate.11.1.xaml C:\TfsData\Build\_work\1\s\BuildProcessTemplates\LabDefaultTemplate.11.xaml C:\TfsData\Build\_work\1\s\BuildProcessTemplates\UpgradeTemplate.xaml C:\TfsData\Build\_work\1\s\checkin-changes.ps1 C:\TfsData\Build\_work\1\s\update.txt C:\TfsData\Build\_work\1\s\updatefile.ps1. 

Specify a shorter path." ---> Microsoft.TeamFoundation.InvalidPathException: TF400889: The following path contains more than the allowed 259 characters: C:\TfsData\Build\_work\1\s\BuildProcessTemplates\AzureContinuousDeployment.11.xaml C:\TfsData\Build\_work\1\s\BuildProcessTemplates\DefaultTemplate.11.1.xaml C:\TfsData\Build\_work\1\s\BuildProcessTemplates\LabDefaultTemplate.11.xaml ...
    at System.IO.PathHelper.GetFullPathName()
    at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength, Boolean expandShortPaths)
    at System.IO.Path.GetFullPathInternal(String path)
    at Microsoft.TeamFoundation.Common.FileSpec.GetFullPathWrapper(String path)
    --- End of inner exception stack trace ---
    at Microsoft.TeamFoundation.Common.FileSpec.GetFullPathWrapper(String path)
    at Microsoft.TeamFoundation.Common.FileSpec.GetFullPath(String path, Boolean checkForIllegalDollar)
    at Microsoft.TeamFoundation.VersionControl.Common.VersionControlUtil.GetFullPath(String item, PathLength maxServerPathLength)
    at Microsoft.TeamFoundation.VersionControl.Client.ItemSpec..ctor(String item, RecursionType recursionType, Int32 deletionId)
    at Microsoft.TeamFoundation.VersionControl.Client.ItemSpec.FromStrings(String[] paths, RecursionType recursion)
    at 

这表明它正在调用正确的重载

Microsoft.TeamFoundation.VersionControl.Client.Workspace.GetPendingChanges(String[] items, RecursionType recursion, Boolean includeDownloadInfo)

cmdlet返回List<string>以下内容:

protected override void ProcessRecord()
{
    base.ProcessRecord();
    if (!this.IncludeFiles && !this.IncludeFolders)
    {
        this.IncludeFiles = true;
    }
    List<string> sendToPipeline = FindFiles.FindMatchingFiles(this.RootFolder, this.SearchPattern, this.IncludeFiles, this.IncludeFolders);
    base.WriteObject(sendToPipeline, true);
}

为了确保我从Find-Files的电话中获得了一个列表,我添加了:

Write-Verbose "Found files: " -Verbose
Write-Verbose $FilesToCheckin.Count -Verbose

返回:7,正如所料。

我的问题

如何阻止Powershell将结果从find-files转换为一个长字符串,然后再将其传递给GetPendingChanges

项目可用,底部注释掉的破碎代码:

2 个答案:

答案 0 :(得分:1)

您是否尝试通过反射调用方法来强制正确的重载?类似的东西:

[Object[]] $parameters = @($stringArray)
$methods = $provider.Workspace.GetType().GetMethods() | where {$_.Name -eq "GetPendingChanges" -and $_.GetParameters()[0].ParameterType.ToString() -eq "System.String[]" } | Select-Object $_
$methods[0].Invoke($provider.Workspace, $parameters);

答案 1 :(得分:0)

我不知道为什么会这样,但是在将@()添加到[string[]]之后到处都放置Write-Verbose $FilesToCheckin并删除if ($ItemSpec.Contains("*") -Or $ItemSpec.Contains("?")) { Write-Verbose "Pattern found in solution parameter. Calling Find-Files." Write-Verbose "Calling Find-Files with pattern: $ItemSpec" [string[]] $FilesToCheckin = @(Find-Files -SearchPattern $ItemSpec -RootFolder $env:BUILD_SOURCESDIRECTORY) } else { Write-Verbose "No Pattern found in solution parameter." [string[]] $FilesToCheckin = @($ItemSpec) } $pendingChanges = $provider.Workspace.GetPendingChanges( [string[]] @($FilesToCheckin) ) 它有效:

setItem()