【问题标题】:Powershell start-job -scriptblock cannot recognize the function defined in the same file?Powershell start-job -scriptblock 无法识别同一文件中定义的函数?
【发布时间】:2013-05-16 13:34:47
【问题描述】:

我有以下代码。

function createZip
{
Param ([String]$source, [String]$zipfile)
Process { echo "zip: $source`n     --> $zipfile" }
}

try {
    Start-Job -ScriptBlock { createZip "abd" "acd" } 
}
catch {
    $_ | fl * -force
}
Get-Job | Wait-Job 
Get-Job | receive-job 
Get-Job | Remove-Job 

但是,脚本返回以下错误。

Id              Name            State      HasMoreData     Location             Command                  
--              ----            -----      -----------     --------             -------                  
309             Job309          Running    True            localhost            createZip "a...
309             Job309          Failed     False           localhost            createZip "a...
Receive-Job : The term 'createZip' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:17 char:22
+ Get-Job | receive-job <<<<  
    + CategoryInfo          : ObjectNotFound: (function:createZip:String) [Receive-Job], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

start-job 的脚本块中似乎无法识别函数名称。我也试过function:createZip

【问题讨论】:

    标签: powershell powershell-2.0


    【解决方案1】:

    Start-Job 实际上启动了另一个没有 createZip 函数的 PowerShell.exe 实例。您需要将其全部包含在脚本块中:

    $createZip = {
        param ([String]$source, [String]$zipfile)
        Process { echo "zip: $source`n     --> $zipfile" }
    }
    
    Start-Job -ScriptBlock $createZip  -ArgumentList "abd", "acd"
    

    从后台作业返回错误消息的示例:

    $createZip = {
        param ([String] $source, [String] $zipfile)
    
        $output = & zip.exe $source $zipfile 2>&1
        if ($LASTEXITCODE -ne 0) {
            throw $output
        }
    }
    
    $job = Start-Job -ScriptBlock $createZip -ArgumentList "abd", "acd"
    $job | Wait-Job | Receive-Job
    

    另请注意,通过使用 throw,作业对象 State 将“失败”,因此您只能获取失败的作业:Get-Job -State Failed

    【讨论】:

    • 谢谢。似乎无法捕获在另一个 PowerShell 实例中引发的异常。捕获异常的最佳方法是什么?
    • 谢谢你 - 我有一个类似的问题,现在我很高兴!
    【解决方案2】:

    如果您对使用 start-job 和 receive-job 还很陌生,并且想更轻松地调试您的功能,请尝试以下表单:

       $createZip = { 
       function createzipFunc {
         param ([String]$source, [String]$zipfile)
         Process { echo "zip: $source`n     --> $zipfile" }
         }
         #other funcs and constants here if wanted...
       }
       # some secret sauce, this defines the function(s) for us as locals
       invoke-expression $createzip
    
       #now test it out without any job plumbing to confuse you
       createzipFunc "abd" "acd"
    
       # once debugged, unfortunately this makes calling the function from the job  
       # slightly harder, but here goes...
       Start-Job -initializationScript $createZip -scriptblock {param($a,$b) `
    createzipFunc $a $b } -ArgumentList "abc","def"
    

    我没有像你那样将我的函数定义为一个简单的过滤器,这并没有让一切变得更简单,但我之所以这样做是因为我想最终将一些函数传递给我的 Job。

    很抱歉挖掘了这个线程,但它也解决了我的问题,而且非常优雅。所以我只需要添加一点点我在调试我的 powershell 工作时写的酱汁。

    【讨论】:

    • 我喜欢这种方法。要添加的一件事是有时Invoke-Expression 会抱怨Invoke-Expression : Cannot evaluate parameter 'Command' because its argument is specified as a script block and there is no input. A script block cannot be evaluated without input.。我发现如果你将变量作为字符串传递 invoke-expression "$createzip" 可以解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-12
    • 2017-06-21
    相关资源
    最近更新 更多