PowerShell循环并行执行EXE并等待完成:程序启动即关闭问题
问题分析
你的代码存在两个核心问题:
- 变量作用域问题:
Start-Job的脚本块运行在独立的PowerShell会话中,无法直接访问外部的$item变量,导致传递给Console.exe的/Id:参数值为空,程序因参数错误启动后立即退出。 - 未等待程序执行完成:
Start-Process默认不会等待目标程序运行结束,即使变量传递正确,Start-Job也会在启动程序后立刻标记为完成,无法确保程序执行完毕。
解决方案
方案1:并行执行所有任务(保留Job机制)
修正变量传递和等待逻辑,确保每个Job等待Console.exe执行完成后再结束:
$jobArray = New-Object -TypeName System.Collections.ArrayList ForEach ($item in Get-Content C:\items.txt) { # 通过-ArgumentList传递$item,在脚本块中用param接收 $job = Start-Job -ScriptBlock { param($targetItem) # 使用-Wait参数等待程序执行完成,-NoNewWindow避免弹出新窗口(可选) Start-Process "C:\Development\Console.exe" -ArgumentList "/count", "/Id:$targetItem", "/verbose" -Wait -NoNewWindow } -ArgumentList $item $jobArray.Add($job) | Out-Null # 抑制ArrayList.Add的返回值输出 } Write-Verbose "所有任务已启动" -Verbose # 等待所有Job完成 $jobArray | Wait-Job # 可选:获取Job的执行结果 $jobArray | Receive-Job # 清理Job $jobArray | Remove-Job
方案2:串行执行任务(无需Job)
如果不需要并行执行,直接在循环中等待每个程序完成后再处理下一个,代码更简洁:
ForEach ($item in Get-Content C:\items.txt) { Start-Process "C:\Development\Console.exe" -ArgumentList "/count", "/Id:$item", "/verbose" -Wait -NoNewWindow Write-Verbose "处理完成:$item" -Verbose } Write-Verbose "所有任务执行完毕" -Verbose
关键说明
-ArgumentList:用于将外部变量传递给Start-Job的脚本块,必须配合脚本块内的param声明接收。-Wait:让Start-Process等待目标程序退出后再继续执行后续代码。-NoNewWindow:可选参数,避免每次启动程序都弹出新的控制台窗口,若你需要看到程序输出可以去掉该参数。
内容的提问来源于stack exchange,提问作者mgn93
相关产品推荐
相关产品推荐

