我正在管道一個數據的數組到一個可執行程序,但我需要它在foreach循環中每次調用後阻止。它會在第一次調用打開程序之前離開循環。Powershell管道進入EXE和等待
Set-Alias program "whatever.exe"
foreach ($data in $all_data)
{
$data| %{ program /command:update /path:"$_" /closeonend:2 }
}
我正在管道一個數據的數組到一個可執行程序,但我需要它在foreach循環中每次調用後阻止。它會在第一次調用打開程序之前離開循環。Powershell管道進入EXE和等待
Set-Alias program "whatever.exe"
foreach ($data in $all_data)
{
$data| %{ program /command:update /path:"$_" /closeonend:2 }
}
我喜歡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.
}
}
}
我能想到的兩種方法來解決這個:
我讓你的示例代碼更加具體一些,這樣我就可以運行和測試我的解決方案;希望它會翻譯。以下是我開始時的等同示例代碼,即腳本執行時不會等待可執行文件完成。
# 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 "$_" }
這與您的問題無關,但您的代碼中存在不必要的'foreach'循環。您可以簡化環路的其中之一: '的foreach($ $中的數據all_data) { 程序/命令:update /路徑:$數據/ closeonend:2} }' 或 '$ all_data | %{program/command:update/path:「$ _」/ closeonend:2}' –
所以「你需要等到外部調用完成才能進行下一次迭代」? – Neolisk