从开始作业中获取PID

时间:2019-08-01 23:19:19

标签: powershell

我在Powershell(最新版​​本)的“启动作业”中无法从启动进程获取PID。在Start-Job脚本块之外运行时,Start-Process cmdlet会运行并按预期返回PID。将语句添加到“开始作业”脚本块后,将不返回任何PID。有人可以指出这个新手正确的方向吗?

$myJob = Start-Job -Name newJob -ScriptBlock {
$procID = (Start-Process myprogram.exe -PassThru -ArgumentList "myArgs" -WorkingDirectory "myWorkingDir").Id
}

1 个答案:

答案 0 :(得分:1)

也许您认为分配给在后台作业中执行的脚本块中的变量会使该变量对调用方可见,而不是。 / p>

后台作业在完全独立的会话中运行,并且为了与调用方通信数据,必须使用成功的输出流,调用方必须通过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,但不要使用t使用Start-Process启动myprogram.exe:直接从后台作业 调用它:

$myJob = Start-Job -Name newJob -ScriptBlock {
  Set-Location "myWorkingDir"
  myprogram.exe
}

虽然不会为您提供该进程的ID,但是您可以使用启动该进程的 job -$myJob-来跟踪该特定进程及其输出。

>