PowerShell中的调用操作符究竟是做什么的?

时间:2014-04-29 21:32:42

标签: powershell process console-application

我有一个powershell脚本,它使用call运算符运行一些可执行文件。像这样:

$executable = 'c:\dev\test.exe'
& $executable | Out-Host
Write-Host 'done'

test.exe依次运行另一个程序(server.exe)并通过TCP / IP与之通信(此程序需要管理权限,因此我的powershell脚本以管理员身份运行),也是运行琐碎的批处理脚本(运行并在1秒内终止)。启动后,server.exe会一直运行,直到test.exe终止。涉及的所有程序都是控制台应用另一个值得注意的事实是,由于server.exe需要管理员权限,因此它在单独的控制台窗口中运行,而不是test.exe

有时test.exe不会终止server.exe(有时由于崩溃,有时是由于其中的错误)。发生这种情况时,test.exe终止执行后不会返回PowerShell脚本(我不会看到'已完成'正在打印)。如果我手动终止server.exe,我会立即看到'已完成'在powershell控制台中。为什么会这样?为什么powershell会等待进程终止它尚未启动但哪个甚至不在同一个控制台中运行?

在我的调查尝试中,我尝试使用较少量的代码来重现该问题,我创建的test2.exe只运行server.exe(完全相同,我可以访问test.exe个来源)并终止。现在当我运行相同的powershell脚本但test2.exe$executable时,我看到了我最初期望看到的内容:server.exe在单独的窗口中启动,然后完成&#39} ; <{1}}仍在运行时,在powershell窗口中打印(并且powershell脚本终止)。

我在server.exe运行时观看了Process Explorer,我确信在test.exe终止后,server.exe以外没有其他进程正在运行。

我没有找到任何深入解释test.exe运营商做了什么以及等待什么,也许你有一些想法?

更新:我试了&,而不是使用调用运算符运行:

Start-Process

现在$executable = 'c:\dev\test.exe' Start-Process $executable -Wait Write-Host 'done' 在其自己的控制台中运行,终止并且powershell仍在等待test.exe完成。

我还尝试运行批处理脚本:

server.exe

并且工作正常:只要c:\dev\test.exe echo done 终止&#39;完成&#39;打印到控制台和批处理文件停止(test.exe仍在运行)。

另一次更新:更改了脚本以执行以下操作:

server.exe

我在$executable = 'c:\dev\test.exe' $proc = Start-Process $executable -PassThru do { Get-Process -Id $proc.Id Start-Sleep -Seconds 10 } while ($true) 正在运行时几次获得常规Get-Process输出(在test.exe终止后)它开始生成&#34;无法找到具有进程标识符3028&#的进程34;错误。所以我可能会这样。

我尝试的另一件事是:

test.exe

仍然没有运气:$env:PATH += ';c:\dev\;' test.exe Write-Host 'done' 终止,powershell仍在等待test.exe终止。

也尝试了工作方法:

server.exe

除非我终止$job = Start-Job {& 'c:\dev\test.exe'} do { $job Start-Sleep -Seconds 10 } while ($job.JobStateInfo.State -eq [System.Management.Automation.JobState]::Running) Receive-Job $job ,否则它永远不会退出。

1 个答案:

答案 0 :(得分:5)

调用操作符&只是尝试调用其后面的命名命令(应用程序,脚本,函数,cmdlet),并将任何其他参数传递给该命令。此外,&在新范围内执行命令,而.在当前范围内执行命令。在执行应用程序(exe)时,我认为您在新范围内执行并不重要。 exe不会影响PowerShell中的作用域变量。

WRT test.exe行为,在控制台exe完成之前,PowerShell不会将控制权返回给脚本。 Test.exe和test2.exe都是控制台子系统exes对吗? PowerShell与Windows子系统exes的行为不同。它启动它们并立即返回,除非你使用像notepad.exe | Out-Null这样的技巧。