PowerShell:将函数作为参数传递

时间:2014-03-02 15:37:07

标签: powershell parameter-passing calling-convention

我写过函数'A',它将调用许多其他函数之一。为了保存重写函数'A',我想传递函数作为函数'A'的参数调用。例如:

function A{
    Param($functionToCall)
    Write-Host "I'm calling : $functionToCall"
}

function B{
    Write-Host "Function B"
}

Function C{
    write-host "Function C"
}

A -functionToCall C

返回:我正在调用:C

我期待它回归:我正在呼唤:功能C。

我尝试了各种各样的事情,例如:

Param([scriptblock]$functionToCall)

无法将System.String转换为ScriptBlock

A -functionToCall $function:C

返回“写主机”功能C“

A - functionToCall (&C)

在其余部分之前进行评估:

 Function C
 I'm Calling :

我确定这是编程101,但我无法弄清楚正确的语法或它是什么我做错了。我们将非常感激地提供任何帮助。非常感谢。

8 个答案:

答案 0 :(得分:39)

我不确定这是最好的,但是:

function A{
    Param([scriptblock]$FunctionToCall)
    Write-Host "I'm calling $($FunctionToCall.Invoke(4))"
}

function B($x){
    Write-Output "Function B with $x"
}

Function C{
    Param($x)
    Write-Output "Function C with $x"
}

PS C:\WINDOWS\system32> A -FunctionToCall $function:B
I'm calling Function B with 4

PS C:\WINDOWS\system32> A -FunctionToCall $function:C
I'm calling Function C with 4

PS C:\WINDOWS\system32> A -FunctionToCall { Param($x) "Got $x" }
I'm calling Got x

答案 1 :(得分:7)

您是否考虑过将ScriptBlock作为参数传递?

$scriptBlock = { Write-Host "This is a script block" }
Function f([ScriptBlock]$s) {
  Write-Host "Invoking ScriptBlock: "
  $s.Invoke()
}

PS C:\> f $scriptBlock
Invoking ScriptBlock:
This is a script block

答案 2 :(得分:6)

这是你需要的吗?

function A{
    Param($functionToCall)
    Write-Host "I'm calling : $functionToCall"

    #access the function-object like this.. Ex. get the value of the StartPosition property
    (Get-Item "function:$functionToCall").ScriptBlock.StartPosition

}

function B{
    Write-Host "Function B"
}

Function C{
    write-host "Function C"
}


PS> a -functionToCall c

I'm calling : c


Content     : Function C{
                  write-host "Function C"
              }
Type        : Position
Start       : 307
Length      : 43
StartLine   : 14
StartColumn : 1
EndLine     : 16
EndColumn   : 2

答案 3 :(得分:3)

邓肯的解决方案对我很有帮助。但是,当函数名称中包含破折号时,我遇到了一些问题。

我能够通过建立他的第三个例子来解决这个问题:

function A{
    Param([scriptblock]$functionToCall)
    Write-Host "I'm calling $($functionToCall.Invoke(4))"
}

function Execute-FunctionWithDash($x)
{
    Write-Output "Function Execute-FunctionWithDash with $x"
}

PS C:\WINDOWS\system32> A -functionToCall { Param($x) Execute-FunctionWithDash $x }
I'm calling Function Execute-FunctionWithDash with 4

答案 4 :(得分:1)

传递可变数量的命名参数

function L($Lambda){
   write-host "`nI'm calling $Lambda"
   write-host "`nWith parameters"; ft -InputObject $Args
   & $Lambda @Args
}

似乎适用于奇怪的函数名称

function +Strange-Name($NotUsed,$Named1,$Named2){
   ls -filter $Named1 -Attributes $Named2
}

PS C:\>L +Strange-Name -Named1 *.txt -Named2 Archive

和exe文件

PS C:\>L grep.exe ".*some text.*" *.txt

虽然看起来你还需要注意注射

function inject($OrigFunction){
   write-host 'pre-run injection'
   & $OrigFunction @Args
   write-host 'post-run injection'
}

PS C:\>L inject +Strange-Name -Named1 *.txt -Named2 Archive

答案 5 :(得分:1)

如果您确实要传递函数的名称,作为 string :请使用&,即调用运算符< / em> ,以调用它:

function A {
  Param($functionToCall)
  # Note the need to enclose a command embedded in a string in $(...)
  Write-Host "I'm calling: $(& $functionToCall)"
}

Function C {
  "Function C"  # Note: Do NOT use Write-Host to output *data*.
}

A -functionToCall C

关于需要在$(...)中使用"..."的信息:请参阅this answer,它解释了PowerShell的字符串扩展(字符串插值)规则。

以上产生I'm calling: Function C

请注意函数C如何使用隐式输出(与显式使用Write-Output相同)返回值。
 Write-Host is generally the wrong tool to use,除非意图是明确地仅写入显示内容,而绕过PowerShell的输出流。

在以下情况下,通常需要&运算符:

  • 要通过名称或路径,通过变量引用和/或名称是单引号还是双引号来调用命令。

  • 调用脚本块

脚本块是在PowerShell中传递代码段的首选方式;上面的内容可以重写为(请注意,调用机制不会改变,只是传递了参数):

function A {
  Param($scriptBlockToCall)
  Write-Host "I'm calling: $(& $scriptBlockToCall)"
}

Function C {
  "Function C"  # Note: Do NOT use Write-Host to output *data*.
}

A -scriptBlockToCall { C }

在两种情况下,要传递参数 ,只需将它们放在以下位置:& <commandNameOrScriptBlock>;请注意如何使用splatting@<var>)来传递存储在自动变量$Args中的未绑定参数。

function A {
  Param($commandNameOrScriptBlockToCall)
  Write-Host "I'm calling: $(& $commandNameOrScriptBlockToCall @Args)"
}

Function C {
  "Function C with args: $Args"
}


A -commandNameOrScriptBlockToCall C one two # by name
A -commandNameOrScriptBlockToCall { C @Args } one two # by script block

上面的方法两次产生I'm calling: Function C with args: one two

答案 6 :(得分:1)

python3 -c "import sys; print(sys.path)"

函数“ substr”将函数“ strdel”称为$ a参数。

https://github.com/brandoncomputer/vds中的功能

答案 7 :(得分:0)

怎么样:

function A{
Param($functionToCall)
    $res = Invoke-Command $functionToCall 
    Write-Host "I'm calling : $res"
}

function B{
    "Function B"
}

Function C{
    "Function C"
}

A -functionToCall ${function:C}

使用$ {function:...}将函数作为值进行路径传递。 调用该函数并将结果保存到$ res。