如何通过读取msbuild项目为脚本cmdlet生成动态参数?

时间:2011-08-05 22:07:18

标签: powershell msbuild

我正在尝试为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
}

1 个答案:

答案 0 :(得分:3)

我建议您不要添加一堆开关参数。而是添加一个名为“Target”的动态参数,并使用目标列表向其添加ValidateSet属性。

这是一篇有用的文章。

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