也许您认为分配给在后台作业中执行的脚本块中的变量会使该变量对调用者可见,但不是的情况。
后台作业在一个完全独立的会话中运行,为了将数据传递给调用者,必须使用成功输出流,调用者必须通过Receive-Job cmdlet 收集其内容:
$myJob = Start-Job -Name newJob -ScriptBlock {
# Implicitly output the PID of then newly launched process.
(Start-Process myprogram.exe -PassThru -ArgumentList "myArgs" -WorkingDirectory "myWorkingDir").Id
}
# Use Receive-Job to collect the background job's output, once available.
# NOTE: If `Start-Process` failed, this would result in an infinite loop.
# Be sure to implement a timeout.
# You could use `$procID = Receive-Job -Wait -AutoRemoveJob` to wait synchronously,
# but that would defeat the purpose of a background job (see below).
while (-not ($procID = Receive-Job $myjob)) {
Start-Sleep -Milliseconds 200
}
退一步:Start-Process 本身是异步的,因此无需使用后台作业:只需在调用者的上下文中直接启动myprogram.exe:
# Launch myprogram.exe asynchronously.
# $proc receives a value once the program has *launched* and
# your script continues right after.
$proc = Start-Process myprogram.exe -PassThru -ArgumentList "myArgs" -WorkingDirectory "myWorkingDir"
# $proc.Id retrieves the PID (process ID)
# $proc.HasExited tells you whether the process has exited.
# $proc.WaitForExit() allows you to wait synchronously to wait for the process to exit.
但是,如果myprogram.exe 是一个控制台(终端)应用程序,您要捕获其输出,请使用Start-Job,但不要使用@987654328 @ 启动 myprogram.exe:从后台作业直接调用它:
$myJob = Start-Job -Name newJob -ScriptBlock {
Set-Location "myWorkingDir"
myprogram.exe
}
虽然这不会为您提供该进程的 ID,但您可以改为使用启动该进程的 作业 - $myJob - 来跟踪该特定进程及其输出。