2010-02-15 112 views
0

使用自定義Powershell函數將返回所有函數輸出。我試圖通過編寫一個只返回$ true或$ false的包裝函數來消除這種限制/混淆。Powershell - 動態函數調用

但是,我正在努力與動態函數調用。 。 。專門傳遞參數。

請注意函數名稱和函數參數都傳遞給「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是這可能嗎?

謝謝。

回答

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

在這裏,我們傳遞的功能只有一個參數-an在Foo默認基於陣列所以第二個參數0

如果你只是想放棄語句/表達式的輸出,有辦法做到這一點,例如管道到Out-Null或「鑄造」到void

+0

謝謝,是的,我明白髮生了什麼事。我認爲/希望$ oArgs [0 ..($ oArgs.Length - 1)]不會被視爲一個數組,而是一個參數列表0,1,2等。 我知道「out-null 「技巧,但我試圖避免當開發人員忘記使用它或只是不知道哪些語句返回輸出時出現的問題。 – MattH 2010-02-15 23:49:28

2

我會用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。欲瞭解更多信息看How and Why to Use Splatting (passing [switch] parameters)

0

就個人而言,我只想用:

functionName -as [bool] 

這將迫使該函數的結果轉換成一個布爾值。

以後可讀性更強。

希望這可以幫助

+0

根據您的經驗,即使函數具有其他輸出,它是否可靠地強制布爾結果? – MattH 2010-02-17 17:01:20