【发布时间】:2014-07-31 00:01:01
【问题描述】:
我有一个带有八个参数的 powershell 函数。两个是强制性的,两个是互斥的。这给了我函数调用的 24 种排列。
似乎我应该能够根据参数数据的存在来制作一个字符串,然后执行该字符串来调用该函数,但我还没有找到解决方案。
这是 XML 输入,括号 [] 中的参数是可选的,|表示非此即彼:
<TextInsert TargetFile="" StartString="" [IncludeStartString="True"] [EndString="" [IncludeEndString="True"]] [SourceFile=""|InsertText=""] [IgnoreCase="True"] />
我曾尝试通过在发现变量时将变量连接到调用来构造函数调用,如下所示:
Function MakeInsertTextFunctionCallI {
param (
[System.Xml.XmlElement]$Params
)
$IgnoreCase = $Params.IgnoreCase
$StartString = $Params.StartString
$IncludeStart = $Params.IncludeStartString
$EndString = $Params.EndString
$IncludeEnd = $Params.IncludeEndString
$TargetFile = $Params.TargetFile
$InsertText = $Params.InsertText
$SourceFile = $Params.SourceFile
# Section A #############################################################
$CmdStr = "InsertText -File $TargetFile -StartString $StartString"
If($IncludeStart) {
$CmdStr += " -IncludeStartString"
}
If($SourceFile) {
$CmdStr += " -SourceFile $SourceFile"
} else {
$CmdStr += " -InsertText $InsertText"
}
If($EndString) {
$CmdStr += " -EndString $EndString"
If($IncludeEnd) {
$CmdStr += " -IncludeEndString"
}
}
If($IgnoreCase) {
$CmdStr += " -IgnoreCase"
}
# $CmdStr
# & $CmdStr
Invoke-Expression $CmdStr
但我无法让它工作。我尝试了调用该函数的三种变体。一些问题涉及在参数中嵌入引号。另一个问题是我正在使用它来编辑标记语言文件,因此有很多嵌入的 " 和此类符号。导致最后一次尝试出现此错误:Invoke-Expression : The '
以下代码部分虽然不优雅且不支持,但确实有效:
# Section B ############################################################
#Possible Parameters
$cTargetFile = [Convert]::ToInt32("10000000",2) #128
$cStartString = [Convert]::ToInt32("01000000",2) #64
$cIncludeStart = [Convert]::ToInt32("00100000",2) #32
$cSourceFile = [Convert]::ToInt32("00010000",2) #16
$cInsertText = [Convert]::ToInt32("00001000",2) #8
$cEndString = [Convert]::ToInt32("00000100",2) #4
$cIncludeEnd = [Convert]::ToInt32("00000010",2) #2
$cIgnoreCase = [Convert]::ToInt32("00000001",2) #1
$ParamMask = 0
If($IgnoreCase) { $ParamMask += $cIgnoreCase }
If($StartString) { $ParamMask += $cStartString }
If($IncludeStart) { $ParamMask += $cIncludeStart }
If($SourceFile) { $ParamMask += $cSourceFile }
If($InsertText) { $ParamMask += $cInsertText }
If($EndString) { $ParamMask += $cEndString }
If($IncludeEnd) { $ParamMask += $cIncludeEnd }
If($TargetFile) { $ParamMask += $cTargetFile }
switch($ParamMask) {
192 { InsertText -File $TargetFile -StartString $StartString -SourceFile $SourceFile }
193 { InsertText -File $TargetFile -StartString $StartString -SourceFile $SourceFile -IgnoreCase }
200 { InsertText -File $TargetFile -StartString $StartString -InsertText $InsertText }
201 { InsertText -File $TargetFile -StartString $StartString -InsertText $InsertText -IgnoreCase }
.
. <some of the 24 permutations removed for brevity>
.
246 { InsertText -File $TargetFile -StartString $StartString -IncludeStart -EndString $EndString -IncludeEnd -SourceFile $SourceFile }
247 { InsertText -File $TargetFile -StartString $StartString -IncludeStart -EndString $EndString -IncludeEnd -SourceFile $SourceFile -IgnoreCase }
238 { InsertText -File $TargetFile -StartString $StartString -IncludeStart -EndString $EndString -IncludeEnd -InsertText $InsertText }
239 { InsertText -File $TargetFile -StartString $StartString -IncludeStart -EndString $EndString -IncludeEnd -InsertText $InsertText -IgnoreCase }
Default { #Then log an invalid parameters error}
}
我说 B 部分是不支持的,因为如果有人想在函数中添加另一个参数,计算位掩码并在 switch 语句中输入所有新的排列将过于耗时;而不是仅仅向 A 部分添加一个连接。
有没有人有任何简化此代码的提示?或者对 A 部分的任何批评可能会提高其可操作性?
【问题讨论】:
-
您是否尝试在哈希表中构造您的参数并将其传递给函数?我认为这比尝试进行所有字符串连接要容易得多。
-
@mjolinor 的建议很可能是可行的方法。要查找有关 splatting 的更多信息,请运行命令
Get-Help about_Splatting(或在线阅读相同的帮助部分 technet.microsoft.com/en-us/library/jj672955.aspx)。 -
喷溅“几乎”有效 - 向 [switch] 参数发送值令人讨厌。我试过 "$true",1,$true 但在每种情况下它都说:无法将值 "System.String" 转换为类型 "Syst em.Management.Automation.SwitchParameter",这种类型的参数只接受布尔值或数字,请改用 $true、$false、1 或 0。仍在试图弄清楚这一小块。否则它看起来是一个很好的解决方案。
-
一个解决方案是使用 splatting 除了 switch。
-
我从来没有见过 $true 或 $false(无引号)不能用于喷射开关参数。
标签: powershell