繁体   English   中英

Powershell管道进入exe并等待

[英]Powershell pipe into exe and wait

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

 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 ,则可以使用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. 将可执行调用通过管道传递给Out-Null
  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 "$_" }

根据您的情况, 等待工作可能会过大。 如果您可以通过编程的方式知道what.exe已完成其工作,则可以尝试类似

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

还有

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM