我正在将一组数据传输到一个可执行程序中,但我需要在 foreach 循环中的每次调用后阻塞它。它甚至会在第一次调用打开程序之前离开循环。
Set-Alias program "whatever.exe"
foreach ($data in $all_data)
{
$data| %{ program /command:update /path:"$_" /closeonend:2 }
}
我正在将一组数据传输到一个可执行程序中,但我需要在 foreach 循环中的每次调用后阻塞它。它甚至会在第一次调用打开程序之前离开循环。
Set-Alias program "whatever.exe"
foreach ($data in $all_data)
{
$data| %{ program /command:update /path:"$_" /closeonend:2 }
}
我可以想到两种方法来解决这个问题:
我使您的示例代码更加具体,以便我可以运行和测试我的解决方案;希望它会翻译。这是我开始的与您的示例代码等效的内容,即脚本执行时无需等待可执行文件完成。
# I picked a specific program
Set-Alias program "notepad.exe"
# And put some values in $all_data, specifically the paths to three text files.
$all_data = Get-Item B:\matt\Documents\*.txt
# This opens each file in notepad; three instances of notepad are running
# when the script finishes executing.
$all_data | %{ program "$_" }
这是与上面相同的代码,但管道Out-Null
强制脚本等待循环的每次迭代。
# I picked a specific program
Set-Alias program "notepad.exe"
# And put some values in $all_data, specifically the paths to three text files.
$all_data = Get-Item B:\matt\Documents\*.txt
# Piping the executable call to out-null forces the script execution to wait
# for the program to complete. So in this example, the first document opens
# in notepad, but the second won't open until the first one is closed, and so on.
$all_data | %{ program "$_" | Out-Null}
最后,相同的代码(或多或少)cmd /c
用于调用可执行文件并使脚本等待。
# Still using notepad, but I couldn't work out the correct call for
# cmd.exe using Set-Alias. We can do something similar by putting
# the program name in a plain old variable, though.
#Set-Alias program "notepad.exe"
$program = "notepad.exe"
# Put some values in $all_data, specifically the paths to three text files.
$all_data = Get-Item B:\matt\Documents\*.txt
# This forces script execution to wait until the call to $program
# completes. Again, the first document opens in notepad, but the second
# won't open until the first one is closed, and so on.
$all_data | %{ cmd /c $program "$_" }
我喜欢 PowerShell,但我从未真正学过Invoke-Command
. 因此,每当我需要运行 EXE 时,我总是使用 cmd。如果您键入cmd /?
您会得到它的帮助,请查看“c”开关。我会做这样的事情:
foreach ($data in $all_data){
$data |
Foreach-Object{
cmd /c "whatever.exe" /command:update /path:"$_" /closeonend:2
}
}
如果你不喜欢cmd /c
你可以使用乔布斯的东西。
foreach ($data in $all_data){
$data |
Foreach-Object{
$job = Start-Job -InitializationScript {Set-Alias program "whatever.exe"} -ScriptBlock {program /command:update /path:"$($args[0])" /closeonend:2} -ArgumentList $_
while($job.Status -eq 'Running'){
Start-Sleep -Seconds 3
#Could make it more robust and add some error checking.
}
}
}