【发布时间】: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