【问题标题】:Getting PID from within a Start-Job从 Start-Job 中获取 PID
【发布时间】:2019-08-02 10:30:01
【问题描述】:

我无法从 Powershell(最新版​​本)的 Start-Job 中的 Start-Process 获取 PID。 Start-Process cmdlet 在 Start-Job 脚本块之外运行并按预期返回 PID。当语句被添加到 Start-Job Scriptblock 时,不会返回任何 PID。有人能指出这个新手正确的方向吗?

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

【问题讨论】:

  • 我应该补充一点,可能有多个 myprogram.exe 实例正在运行;因此,Get-Process -Name myprogram.exe |在这种情况下,select Id 将不起作用。
  • 好吧,您将进程 id 值分配给 $procID 并且从不对其进行任何操作。去掉$procID =,job结果应该是myprogram.exe的进程ID

标签: powershell


【解决方案1】:

也许您认为分配给在后台作业中执行的脚本块中的变量会使该变量对调用者可见,但不是的情况。

后台作业在一个完全独立的会话中运行,为了将数据传递给调用者,必须使用成功输出流,调用者必须通过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 - 来跟踪该特定进程及其输出。

【讨论】:

    猜你喜欢
    • 2021-11-22
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    • 2015-06-23
    • 1970-01-01
    • 2011-04-25
    相关资源
    最近更新 更多