1

很简单,我试图通过调用 Powershell 中 VersionControlServer 类的 QueryWorkspaces 方法来获取工作区列表。我将 null 传递给参数,根据文档,它应该给我一个工作区列表。

如果我命名工作区,它可以正常工作并返回一个工作区,但文档说空名称应该给所有工作区。

function Get-Workspace
{
    param
    (
        [Parameter(Mandatory=$true)]
        [string]$TeamProjectCollection,
        [string]$Owner,
        [string]$Computer,
        [parameter(ValueFromPipeline=$true)]
        [string]$Name
    )

    begin
    {    
        [Microsoft.TeamFoundation.Client.TfsTeamProjectCollection]$tfsTeamProjectCollection = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($TeamProjectCollection)
        [Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer]$versionControlServer = $tfsTeamProjectCollection.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
    }

    process
    {
        Write-Output $versionControlServer.QueryWorkspaces($Name, $Owner, $Computer)
    }
}

我正在使用项目集合管理员权限运行。

4

2 回答 2

2

问题似乎是当 .net 类需要字符串时,PowerShell 不会将 null 作为 null 传递。在 PowerShell 层的某个地方,null 被转换为空字符串。这阻止了返回所有工作区的代码路径执行。相反,它试图匹配一个名为“”的工作区。

该问题的详细信息在Microsoft Connect 文章中,该文章报告该问题将在 PowerShell 3.0 中修复。

知道了问题所在以及如何解决问题的提示后,我开始了反射路线。然而,这变得更加复杂,因为 QueryWorkspaces 方法被重载,因此对 GetType 的简单调用引发了异常。尝试将类型数组传递给 GetType 调用失败,因为 PowerShell 将其作为 Object 数组而不是 Type 数组传递。因此,它必须长期完成......

function Get-Workspace
{
    param
    (
        [Parameter(Mandatory=$true)]
        [string]$TeamProjectCollection,
        [string]$Owner,
        [string]$Computer,
        [parameter(ValueFromPipeline=$true)]
        [string]$Name
    )

    begin
    {    
        [Microsoft.TeamFoundation.Client.TfsTeamProjectCollection]$tfsTeamProjectCollection = [Microsoft.TeamFoundation.Client.TfsTeamProjectCollectionFactory]::GetTeamProjectCollection($TeamProjectCollection)
        [Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer]$versionControlServer = $tfsTeamProjectCollection.GetService([Microsoft.TeamFoundation.VersionControl.Client.VersionControlServer])
        [array]$methods = $versionControlServer.GetType().GetMethods()
        [System.Reflection.MethodInfo]$methodToInvoke = $null
        foreach($method in $methods)
        {
            if ($method.Name -eq "QueryWorkspaces")
            {
                if ($method.GetParameters().Length -eq 3)
                {
                    $methodToInvoke = $method
                }
            }
        }
    }

    process
    {
        if ([string]::IsNullOrEmpty($Name))
        {
            $params = @($null, $Owner, $Computer)
            Write-Output $methodToInvoke.Invoke($versionControlServer, $params)
        }
        else
        {
            Write-Output $versionControlServer.QueryWorkspaces($Name, $userName, $computerName)
        }
    }
}
于 2012-12-04T11:27:28.970 回答
0

是否曾经使用$null

[System.Management.Automation.Language.NullString]::Value

代替$null

(PowerShell 无法正确处理$null并被解释为""

于 2017-10-19T19:15:30.430 回答