【问题标题】:How to generate dynamic parameters for script cmdlet by reading an msbuild project?如何通过读取 msbuild 项目为脚本 cmdlet 生成动态参数?
【发布时间】:2011-08-05 22:07:18
【问题描述】:

我正在尝试为 MSBuild 项目文件中的每个目标创建一个带有动态参数的脚本 cmdlet。它有一个小烦恼 - 它只会自动完成静态参数,直到我输入目标参数的第一个字符。

下面是我的带有 cmdlet“Make-Project”的脚本。

什么会导致 DynamicParam 不返回参数,除非输入参数的第一部分?

Set-Alias mk Make-Project

function Make-Project
{
    [CmdletBinding(DefaultParameterSetName="Build")]
    PARAM(
        [Parameter(ParameterSetName="Build")]
        [Switch]$Build,

        [Parameter(ParameterSetName="Clean")]
        [Switch]$Clean,

        [Parameter(ParameterSetName="Rebuild")]
        [Switch]$Rebuild,

        [ValidateSet( "q","quiet", "m","minimal", "n","normal", "d","detailed", "diag","diagnostic" )]
        [string]$BuildVerbosity,

        [Switch]$CertificationBuild,

        [Switch]$BuildDebug
    )

    PROCESS
    {
        # Defaults
        $certBuild = ""
        $target = "Usage"
        $buildTarget = "Build"
        $verbosity = "minimal"
        $configuration = "release"

        if ( [System.Convert]::ToBoolean( $env:project_build_debug ) )
            { $configuration = "debug" }

        foreach( $paramName in $MyInvocation.BoundParameters.Keys )
        {
            switch -RegEx ( $paramName )
            {
                "(?i)CertificationBuild"    { $certBuild = "cert" }
                "(?i)^(Build|Clean|Rebuild)$"   { $buildTarget = $paramName }
                "(?i)^BuildVerbosity$"      { $verbosity = $MyInvocation.BoundParameters[ $paramName ] }
                "(?i)^BuildDebug$"      { $configuration = "debug" }
                default             { $target = $paramName }
            } 
        }
        $msbuildexe = Get-MSBuildExe
        if ( $msbuildexe.Contains( "v4.0" ) )
            { $cmd = "$msbuildexe /v:$verbosity $certBuild /m /property:Configuration=$configuration /property:BuildTarget=$buildTarget /target:$target /property:CLR4=1 Project.proj" }
        else
            { $cmd = "$msbuildexe /v:$verbosity $certBuild /m /property:Configuration=$configuration /property:BuildTarget=$buildTarget /target:$target /tv:3.5 Project.proj" }
        Write-Host $cmd
        Invoke-Expression $cmd
    }

    DynamicParam
    {
        $projFile = '.\Project.Proj'
        $projXml = [xml]( Get-Content $projFile )

        $paramDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary
        $projXml.Project.Target | % { 
            $paramName = $_.Name
            $attribute = New-Object System.Management.Automation.ParameterAttribute
            $attribute.ParameterSetName = "__AllParameterSets"
            $attribute.Mandatory = $false
            $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute]
            $attributeCollection.Add($attribute)

            $param = New-Object System.Management.Automation.RuntimeDefinedParameter( $paramName, [Switch], $attributeCollection )
            $paramDictionary.Add( $paramName, $param )
        }
        return $paramDictionary
    }
}

function Get-MSBuildExe
{
    $bitness = ""
    if ( $env:PROCESSOR_ARCHITECTURE -eq "AMD64" )
        { $bitness = "64" }

    $msbuildexe = "$env:SystemRoot\Microsoft.NET\Framework${bitness}\v4.0.30319\MSBuild.exe"
    if ( -not (Test-Path $msbuildexe) )
        { $msbuildexe = "$env:SystemRoot\Microsoft.NET\Framework${bitness}\v3.5\MSBuild.exe" }

    $msbuildexe
}

【问题讨论】:

  • 你的意思是在输入 cmdlet 名称后不能点击选项卡,你必须输入“B”、“C”或“R”(用于构建、清理或重建)然后点击选项卡自动完成是做什么的?如果是这样,这是因为在您给出提示之前,命令行不会知道您要使用的参数集。
  • 是的。我假设“__AllParameterSets”参数集名称将允许它继续并返回那些动态开关。如果我输入动态开关的第一个字符 - 没有其他静态开关 - 制表符补全适用于所有动态开关。

标签: powershell msbuild


【解决方案1】:

我建议你不要添加一堆开关参数。相反,添加一个名为“Target”的动态参数,并在目标列表中添加一个 ValidateSet 属性。

这是一篇很有帮助的文章。

http://robertrobelo.wordpress.com/2010/02/12/add-parameter-validation-attributes-to-dynamic-parameters/

【讨论】:

  • 除了没有带有开关值的选项卡完成/发现,只有开关。我的目标是不必记住和输入完整的目标名称。
  • 有了 PowerTab。 ;) 如果您提供错误的目标名称,您将收到包含有效值列表的错误消息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-20
  • 2012-12-28
  • 1970-01-01
  • 2019-09-01
相关资源
最近更新 更多