Powershell管道进入exe并等待

时间:2013-05-22 15:59:50

标签: powershell

我正在将一个数据数组连接到一个可执行程序中,但我需要在foreach循环中的每次调用之后阻塞它。它会在第一次调用之前打开程序之前离开循环。

 Set-Alias program "whatever.exe"

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

3 个答案:

答案 0 :(得分: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,可以使用Jobs。

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

答案 1 :(得分:2)

我可以想出两种方法来解决这个问题:

  1. 将您的可执行调用传递给Out-Null
  2. shell对cmd.exe / c的调用(如@ BobLobLaw的回答所示)
  3. 我使您的示例代码更加具体,因此我可以运行并测试我的解决方案;希望它会翻译。这是我开始使用的等同于您的示例代码,即脚本执行时无需等待可执行文件完成。

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

答案 2 :(得分:0)

根据您的情况,wait-job可能有点矫枉过正。如果您有一种编程方式来知道无论什么程序已经完成了它的事情,您可以尝试像

这样的东西

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

and