【发布时间】:2014-04-29 21:32:42
【问题描述】:
我有一个 powershell 脚本,它使用调用运算符运行一些可执行文件。像这样的:
$executable = 'c:\dev\test.exe'
& $executable | Out-Host
Write-Host 'done'
test.exe 反过来运行另一个程序 (server.exe) 并通过 TCP/IP 与其通信(该程序需要管理权限,因此我的 powershell 脚本以管理员身份运行),它也运行简单的批处理脚本(运行并在 1 秒内终止)。一旦启动,server.exe 将一直运行,直到被 test.exe 终止。所有涉及的程序都是控制台应用程序。另一个可能值得注意的事实是,由于server.exe 需要管理员权限,因此它在与test.exe 不同的控制台窗口中运行。
有时test.exe 不会终止server.exe(有时是由于崩溃,有时是由于其中的错误)。发生这种情况时,test.exe 终止执行后不会返回到 powershell 脚本(我没有看到打印“完成”)。如果我手动终止 server.exe,我会立即在 powershell 控制台中看到“完成”。为什么会这样?为什么powershell等待进程终止它没有启动,甚至没有在同一个控制台中运行?
在我的调查尝试中,我尝试用更少的代码重现问题,我创建了 test2.exe,它只是运行 server.exe(完全相同,我可以访问 test.exe 源)并终止。现在,当我运行相同的 powershell 脚本但使用 test2.exe 和 $executable 时,我看到的正是我最初期望看到的:server.exe 在单独的窗口中启动,然后在 powershell 窗口中打印“完成”(并且 powershell 脚本终止) 而server.exe 仍在运行。
我在 test.exe 运行时观看了 Process Explorer,我确信在 test.exe 终止后除了 server.exe 之外没有其他进程正在运行。
我没有找到任何深入的解释 & 运算符做什么以及它在等待什么,也许你有一些想法?
更新:我尝试了Start-Process,而不是使用呼叫操作员运行:
$executable = 'c:\dev\test.exe'
Start-Process $executable -Wait
Write-Host 'done'
现在test.exe 在它自己的控制台中运行,终止并且powershell 仍在等待server.exe 完成。
我也尝试运行批处理脚本:
c:\dev\test.exe
echo done
它工作正常:只要test.exe 终止,“完成”就会打印到控制台并且批处理文件停止(server.exe 仍在运行)。
另一个更新:更改脚本以执行以下操作:
$executable = 'c:\dev\test.exe'
$proc = Start-Process $executable -PassThru
do {
Get-Process -Id $proc.Id
Start-Sleep -Seconds 10
} while ($true)
当test.exe 正在运行时,我得到了几次常规的Get-Process 输出然后(在test.exe 终止之后)它开始产生“找不到进程标识符为3028 的进程”错误。所以我大概可以走这条路。
我尝试的另一件事是:
$env:PATH += ';c:\dev\;'
test.exe
Write-Host 'done'
仍然没有运气:test.exe 终止,powershell 仍在等待 server.exe 终止。
也尝试了工作方法:
$job = Start-Job {& 'c:\dev\test.exe'}
do
{
$job
Start-Sleep -Seconds 10
} while ($job.JobStateInfo.State -eq [System.Management.Automation.JobState]::Running)
Receive-Job $job
除非我终止server.exe,否则它永远不会退出。
【问题讨论】:
-
Keith Hill 之类的人对您的回复可能让我不知所措,但是您是否考虑过将可执行文件作为一项工作来运行?这样,即使它没有让 PS 知道它由于某种原因已终止,您也应该能够运行 get-process 并检查它是否正在运行,然后采取相应的行动。
-
@TheMadTechnician,我如何将可执行文件作为作业运行?
Start-Job据我所知只能运行powershell脚本。 -
是的,作业是针对脚本的,但这只是意味着您在命令周围加上花括号并将其视为脚本块。
$myjob = Start-job {& test.exe}
标签: powershell process console-application