2013-05-22 99 views
0

我正在管道一個數據的數組到一個可執行程序,但我需要它在foreach循環中每次調用後阻止。它會在第一次調用打開程序之前離開循環。Powershell管道進入EXE和等待

Set-Alias program "whatever.exe" 

foreach ($data in $all_data) 
    { 
     $data| %{ program /command:update /path:"$_" /closeonend:2 } 
    } 
+0

這與您的問題無關,但您的代碼中存在不必要的'foreach'循環。您可以簡化環路的其中之一: '的foreach($ $中的數據all_data) { 程序/命令:update /路徑:$數據/ closeonend:2} }' 或 '$ all_data | %{program/command:update/path:「$ _」/ closeonend:2}' –

+0

所以「你需要等到外部調用完成才能進行下一次迭代」? – Neolisk

回答

0

根據您的情況,wait-job可能是矯枉過正。如果你有一個編程的方式來知道whatever.exe已經做了的事情,你可以嘗試像

do {start-sleep -sec 2} until ($done -eq $true)

and東西。

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. 
     } 
    } 
} 
2

我能想到的兩種方法來解決這個:

  1. 管你的可執行文件調用外空
  2. 通話掏出來的cmd.exe/c(如圖@ BobLobLaw的答案)

我讓你的示例代碼更加具體一些,這樣我就可以運行和測試我的解決方案;希望它會翻譯。以下是我開始時的等同示例代碼,即腳本執行時不會等待可執行文件完成。

# 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 "$_" }