Powershell - динамический вызов функции - PullRequest
0 голосов
/ 16 февраля 2010

С пользовательскими функциями 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?

Спасибо.

Ответы [ 3 ]

2 голосов
/ 16 февраля 2010

Я бы использовал 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 (передавая параметры [switch])

0 голосов
/ 17 февраля 2010

Лично я бы просто использовал:

functionName -as [bool]

Это приведёт результаты функции к логическому значению.

Позже это станет намного более читабельным.

Надеюсь, это поможет

0 голосов
/ 16 февраля 2010
$oResult = & $sFunctionName $oArgs[0..($oArgs.Length - 1)]

Здесь вы передаете функции только один аргумент - массив - поэтому второй параметр в Foo по умолчанию равен 0.

Если вы просто хотите отменить вывод из выражения / выражения, есть способы сделать это, например, передать его по номеру Out-Null или «привести к» void.

...