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

n0r*_*0rd 2 powershell process console-application

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

$executable = 'c:\dev\test.exe'
& $executable | Out-Host
Write-Host 'done'
Run Code Online (Sandbox Code Playgroud)

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

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

在我的调查尝试中,我尝试用我创建的少量代码来重现问题,这些代码test2.exe只是简单地运行server.exe(完全相同的方式,我可以访问test.exe源代码)并终止.现在,当我运行相同的powershell脚本但是使用test2.exeas时$executable,我看到了我最初期望看到的内容:server.exe在单独的窗口中启动,然后在powershell窗口中打印'done'(并且powershell脚本终止),同时server.exe仍然运行.

我在test.exe运行时看过Process Explorer ,我确信server.exetest.exe终止后没有其他进程正在运行.

我没有找到任何深入解释&操作员做什么以及等待什么,也许你有一些想法?

更新:我尝试使用调用运算符而不是运行Start-Process:

$executable = 'c:\dev\test.exe'
Start-Process $executable -Wait
Write-Host 'done'
Run Code Online (Sandbox Code Playgroud)

现在test.exe在它自己的控制台中运行,终止并且powershell仍然等待server.exe完成.

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

c:\dev\test.exe
echo done
Run Code Online (Sandbox Code Playgroud)

并且它工作正常:一旦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)
Run Code Online (Sandbox Code Playgroud)

我在运行时获得常规Get-Process输出几次test.exe(在test.exe终止之后)它开始生成"无法找到具有进程标识符3028的进程"错误.所以我可能会这样做.

我尝试的另一件事是:

$env:PATH += ';c:\dev\;'
test.exe
Write-Host 'done'
Run Code Online (Sandbox Code Playgroud)

但是,没有运气:test.exe终止,powershell仍在等待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
Run Code Online (Sandbox Code Playgroud)

除非我终止,它永远不会退出server.exe.

Kei*_*ill 5

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

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