2012-01-05 24 views
11

Tôi có mã sau đây.Powershell start-job -scriptblock không thể nhận ra hàm được định nghĩa trong cùng một tệp?

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 

Tuy nhiên, tập lệnh trả về lỗi sau.

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 

Có vẻ như tên hàm không thể được nhận dạng bên trong khối tập lệnh start-job. Tôi cũng đã thử function:createZip.

Trả lời

13

Start-Job thực sự quay lên một phiên bản khác của PowerShell.exe không có hàm createZip của bạn. Bạn cần phải bao gồm tất cả trong một khối kịch bản:

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

Start-Job -ScriptBlock $createZip -ArgumentList "abd", "acd" 

Một ví dụ trả lại một thông báo lỗi từ công việc nền:

$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 

Cũng lưu ý rằng bằng cách sử dụng một throw job object State sẽ là " Không thành công "để bạn chỉ có thể nhận được các công việc không thành công: Get-Job -State Failed.

+0

Cảm ơn. Có vẻ như ngoại lệ được nêu trong một phiên bản khác của PowerShell không thể bị bắt. Cách tốt nhất để nắm bắt ngoại lệ là gì? – ca9163d9

+0

@NickW Bạn chắc chắn có thể. Kiểm tra câu trả lời cập nhật của tôi. –

+1

Cảm ơn điều này - Tôi đã có một câu hỏi tương tự và bây giờ tôi là vàng! – marceljg

5

Nếu bạn vẫn là người mới sử dụng khởi động công việc và nhận công việc, và muốn gỡ lỗi chức năng của bạn một cách dễ dàng hơn, hãy thử hình thức này:

$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" 

Tất cả không được thực hiện đơn giản hơn bởi thực tế tôi không xác định chức năng của tôi như một bộ lọc đơn giản như bạn có, nhưng tôi đã làm bởi vì tôi muốn chuyển một số chức năng vào công việc của tôi cuối cùng.

Xin lỗi vì đã đào bài này ra, nhưng nó đã giải quyết được vấn đề của tôi và quá thanh lịch ở đó. Và vì vậy tôi chỉ cần thêm chút nước sốt mà tôi đã viết trong khi gỡ lỗi công việc quyền hạn của mình.

+2

Tôi thích cách tiếp cận này. Một điều cần bổ sung là đôi khi 'Invoke-Expression' sẽ phàn nàn' Invoke-Expression: Không thể đánh giá tham số 'Command' vì đối số của nó được xác định như một khối tập lệnh và không có đầu vào. Một khối tập lệnh không thể được đánh giá mà không có đầu vào.'. Tôi thấy rằng nếu bạn vượt qua biến như một chuỗi 'invoke-expression" $ createzip "' giải quyết vấn đề đó. – Adarsha

Các vấn đề liên quan