Powershell - 动态函数调用

发布于 2024-08-21 20:05:01 字数 1499 浏览 6 评论 0原文

对于自定义 Powershell 函数,所有函数输出都会返回。我试图通过编写一个仅返回 $true 或 $false 的包装函数来消除该限制/混乱。

但是,我正在努力处理动态函数调用。 。 。专门传递参数。

请注意,函数名称和函数参数都传递给“ExecBoolean”。

代码示例:

# Simplifies calls to boolean functions in Powershells scripts
# Helps solve this problem -> http://www.vistax64.com/powershell/107328-how-does-return-work-powershell-functions.html

function Foo([string]$sTest, [int] $iTest)
{
    Write-Host "sTest [" $sTest "]."
    Write-Host "iTest [" $iTest "]."
    if ($iTest -eq 1)
    {
        return $true
    }
    else
    {
        return $false
    }
}

function ExecBoolean ([string] $sFunctionName, [array] $oArgs)
{   
    Write-Host "Array Length = " $oArgs.Length ", Items = [" $oArgs[0..($oArgs.Length - 1)] "]"

    $oResult = & $sFunctionName $oArgs[0..($oArgs.Length - 1)]

    # Powershell returns all function output in oResult, just get the last item in the array, if necessary.                     
    if ($oResult.Length -gt 0) 
    {
        return $oResult[$oResult.Length - 1]
    } 
    else 
    {
        return $oResult
    }
}

$oResult = ExecBoolean "Foo" "String1", 1

Write-Host "Result = " $oResult

当前输出:

Array Length =  2 , Items = [ String1 1 ] 
sTest [ String1 1 ]. 
iTest [ 0 ]. 
Result =  False

所需输出:

Array Length =  2 , Items = [ String1 1 ]
sTest [ String1 ].
iTest [ 1 ].
Result =  True

这在 Powershell v1.0 中可能吗?

谢谢。

With custom Powershell functions all function output is returned. I'm attempting to remove that limitation/confusion by writing a wrapper function that will return just $true or $false.

However, I'm struggling with the dynamic function call . . . specifically passing the arguments.

Note that both the function name and the function arguments are passed to "ExecBoolean".

Code Sample:

# Simplifies calls to boolean functions in Powershells scripts
# Helps solve this problem -> http://www.vistax64.com/powershell/107328-how-does-return-work-powershell-functions.html

function Foo([string]$sTest, [int] $iTest)
{
    Write-Host "sTest [" $sTest "]."
    Write-Host "iTest [" $iTest "]."
    if ($iTest -eq 1)
    {
        return $true
    }
    else
    {
        return $false
    }
}

function ExecBoolean ([string] $sFunctionName, [array] $oArgs)
{   
    Write-Host "Array Length = " $oArgs.Length ", Items = [" $oArgs[0..($oArgs.Length - 1)] "]"

    $oResult = & $sFunctionName $oArgs[0..($oArgs.Length - 1)]

    # Powershell returns all function output in oResult, just get the last item in the array, if necessary.                     
    if ($oResult.Length -gt 0) 
    {
        return $oResult[$oResult.Length - 1]
    } 
    else 
    {
        return $oResult
    }
}

$oResult = ExecBoolean "Foo" "String1", 1

Write-Host "Result = " $oResult

Current Output:

Array Length =  2 , Items = [ String1 1 ] 
sTest [ String1 1 ]. 
iTest [ 0 ]. 
Result =  False

Desired Output:

Array Length =  2 , Items = [ String1 1 ]
sTest [ String1 ].
iTest [ 1 ].
Result =  True

Is this possible in Powershell v1.0?

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

小梨窩很甜 2024-08-28 20:05:01

我会像这样使用 Invoke-Expression

function ExecBoolean ([string] $sFunctionName)
{   
    Write-Host "Array Length = " $args.Length ", Items = [" $args[0..($args.Length - 1)] "]"
    $oResult = Invoke-Expression "$sFunctionName  $($args -join ' ')"
    # Powershell returns all function output in oResult, just get the last item in the array, if necessary.                     
    if ($oResult.Length -gt 0) 
    {
        return $oResult[$oResult.Length - 1]
    } 
    else 
    {
        return $oResult
    }
}
ExecBoolean Foo String1 1

请注意:

  1. 我使用 $args ,恕我直言,它更舒服,因为您不需要将参数作为数组传递。但是,您也可以毫无问题地使用 $oArgs (唯一重要的行是带有 Invoke-Expression 的行)。
  2. 这仅适用于简单类型(字符串、整数等),但不适用于例如 FileInfo,因为对象在 $($args -join ' ') 中转换为字符串
  3. 还有一个选项,但它太冗长了:ExecBoolean Foo @{sTest="String1"; iTest=1}。所以你可以在哈希表中传递参数。当然,您需要更改 Foo 以接受哈希表。在这种情况下,您可以传入任何类型,因为您可以使用 & 运算符调用 Foo。
  4. 请参阅下文

,由于其局限性,我不会推荐这种方法(但可能其他人会提出更好的解决方案)。

如果您只是想确保 Foo 不返回任何输出,您可以创建一个脚本来解析调用 Foo 的其他脚本,并检查对“Foo”的每次调用都必须以 $null = 开头。

如果您切换到PowerShell V2,有更好的方法称为splatting。有关详细信息,请参阅 如何以及为何使用 Splatting(传递 [switch] 参数)

I would use Invoke-Expression like this:

function ExecBoolean ([string] $sFunctionName)
{   
    Write-Host "Array Length = " $args.Length ", Items = [" $args[0..($args.Length - 1)] "]"
    $oResult = Invoke-Expression "$sFunctionName  $($args -join ' ')"
    # Powershell returns all function output in oResult, just get the last item in the array, if necessary.                     
    if ($oResult.Length -gt 0) 
    {
        return $oResult[$oResult.Length - 1]
    } 
    else 
    {
        return $oResult
    }
}
ExecBoolean Foo String1 1

Note that:

  1. I use $args which is imho more comfortable, because you don't to pass the arguments as a array. However, you could use your $oArgs as well with no problem (the only line that matters is the one with Invoke-Expression).
  2. This will work only for simple types (strings, ints, ...), but not for e.g. FileInfo, because the objects are converted to strings in $($args -join ' ').
  3. There is one more option, but it is too verbose: ExecBoolean Foo @{sTest="String1"; iTest=1}. So you would pass parameters in a hashtable. You would need to alter Foo to accept hashtable of course. In this case you could pass any type in, because you could call Foo using & operator.
  4. See below

I would not recommend this approach, because of the limitations (but it can happen that maybe others will come up with better solution).

If you just want to ensure that no output is returned from Foo, you might create a script that parses other scripts that call Foo and checks that every call to "Foo" must be prepended with $null =.

If you switch to PowerShell V2, there is better way called splatting. For more info look at How and Why to Use Splatting (passing [switch] parameters)

塔塔猫 2024-08-28 20:05:01
$oResult = & $sFunctionName $oArgs[0..($oArgs.Length - 1)]

在这里,您只向函数传递一个参数(一个数组),因此 Foo 中的第二个参数默认为 0

如果您只想丢弃语句/表达式的输出,有多种方法可以做到这一点,例如通过管道将其传递到 Out-Null 或“强制转换”为 void

$oResult = & $sFunctionName $oArgs[0..($oArgs.Length - 1)]

Here you're passing the function only one argument —an array— so the second parameter in Foo defaults to 0.

If you just want to discard output from a statement/expression, there are ways to do so, like piping it to Out-Null or "casting" to void.

爱人如己 2024-08-28 20:05:01

就我个人而言,我只会使用:

functionName -as [bool]

这会将函数的结果强制转换为布尔值。

稍后它会更具可读性。

希望这有帮助

Personally, I would just use:

functionName -as [bool]

This will coerce the results of the function into a boolean.

It's much more readable later on.

Hope this helps

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文