能否通过PowerShell启动子进程并创建stdin/stdout管道?
Absolutely! PowerShell absolutely supports spawning child processes with connected stdin/stdout pipes—this is totally equivalent to the C++ functionality you referenced. Let’s walk through how to implement this, since it’s a common scenario but requires using the right tools in PowerShell.
System.Diagnostics.Process Class (Most Flexible) This is the closest match to the C++ Win32 API approach, as PowerShell can directly leverage .NET's Process class to create and manage child processes with full pipe control. Here’s a complete example that mimics the MSDN code’s core behavior:
# Set up process start configuration $processStartInfo = [System.Diagnostics.ProcessStartInfo]@{ FileName = "cmd.exe" UseShellExecute = $false # Critical for pipe redirection RedirectStandardInput = $true RedirectStandardOutput = $true CreateNoWindow = $true # Optional: avoid popping a window } # Initialize and start the process $childProcess = New-Object System.Diagnostics.Process $childProcess.StartInfo = $processStartInfo $childProcess.Start() | Out-Null # Write to the child process's stdin $childProcess.StandardInput.WriteLine("echo Hello from PowerShell's pipe!") $childProcess.StandardInput.WriteLine("exit") # Tell the child to terminate # Read all output from stdout $output = $childProcess.StandardOutput.ReadToEnd() $childProcess.WaitForExit() # Display the result Write-Host "Child process output:`n$output"
Key Details:
UseShellExecute = $false: This disables the Windows shell launcher, which is required to redirect stdin/stdout/stderr directly.RedirectStandardInput/Output = $true: Enables the pipe connections between the parent PowerShell process and the child.- For real-time output (instead of waiting for the child to exit), you can use asynchronous event handlers. Here’s a quick example for streaming output:
$processStartInfo = [System.Diagnostics.ProcessStartInfo]@{ FileName = "ping.exe" Arguments = "localhost -t" UseShellExecute = $false RedirectStandardOutput = $true CreateNoWindow = $true } $childProcess = New-Object System.Diagnostics.Process $childProcess.StartInfo = $processStartInfo $childProcess.EnableRaisingEvents = $true # Register an event handler to capture output as it's generated Register-ObjectEvent -InputObject $childProcess -EventName OutputDataReceived -Action { if ($EventArgs.Data) { Write-Host "Ping Output: $($EventArgs.Data)" } } | Out-Null # Start the process and begin asynchronous output reading $childProcess.Start() | Out-Null $childProcess.BeginOutputReadLine() # Let it run for 5 seconds, then clean up Start-Sleep -Seconds 5 $childProcess.Kill() $childProcess.WaitForExit()
Start-Process (For File Redirection) If you don’t need in-memory pipe communication and just want to redirect to/from files, PowerShell’s built-in Start-Process cmdlet works well:
# Redirect stdout to a file and write to stdin from a file Start-Process -FilePath "cmd.exe" -ArgumentList "/c type stdin.txt" -RedirectStandardInput "stdin.txt" -RedirectStandardOutput "stdout.txt" -NoNewWindow -Wait # Read the output file Get-Content "stdout.txt"
This is simpler but less flexible than the .NET Process class for real-time, in-memory pipe interactions.
- The .NET
System.Diagnostics.Processclass is the way to go for full control over stdin/stdout pipes, mirroring the C++ Win32 API functionality you’re familiar with. - PowerShell’s ability to directly use .NET classes means you have access to all the same low-level process management capabilities as compiled languages like C++.
内容的提问来源于stack exchange,提问作者Shuzheng

