.NET
Process Management
STDOUT
Code Duplication
Programming

How to spawn a process and capture its STDOUT in .NET?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

Spawning another program and reading its output is a standard integration pattern in .NET. The mechanics are simple, but correctness depends on a few flags in ProcessStartInfo, especially when the child process writes both standard output and standard error. The safe approach is to redirect the streams deliberately and avoid deadlocks caused by blocking reads.

Configure ProcessStartInfo Correctly

To capture standard output, UseShellExecute must be false, and RedirectStandardOutput must be true. If you also care about failures, redirect standard error at the same time.

csharp
1using System;
2using System.Diagnostics;
3
4public class Program
5{
6    public static void Main()
7    {
8        var startInfo = new ProcessStartInfo
9        {
10            FileName = "dotnet",
11            Arguments = "--info",
12            RedirectStandardOutput = true,
13            RedirectStandardError = true,
14            UseShellExecute = false,
15            CreateNoWindow = true
16        };
17
18        using var process = new Process { StartInfo = startInfo };
19        process.Start();
20
21        string stdout = process.StandardOutput.ReadToEnd();
22        string stderr = process.StandardError.ReadToEnd();
23        process.WaitForExit();
24
25        Console.WriteLine("STDOUT:");
26        Console.WriteLine(stdout);
27
28        if (!string.IsNullOrWhiteSpace(stderr))
29        {
30            Console.WriteLine("STDERR:");
31            Console.WriteLine(stderr);
32        }
33    }
34}

For small outputs, this pattern is fine. The child process runs, the parent reads both streams, and then you inspect the exit code.

That is the minimal reliable setup. Most broken examples online are missing one of those flags or ignore stderr entirely.

Understand Why Deadlocks Happen

Problems appear when the child process writes enough data to fill one redirected stream while the parent is blocked reading the other. The process waits because its output buffer is full, and the parent waits because it is reading the wrong stream first. That is why real tools should read stdout and stderr concurrently.

In modern .NET, an async helper is usually the cleanest pattern:

csharp
1using System;
2using System.Diagnostics;
3using System.Threading.Tasks;
4
5public static class ProcessRunner
6{
7    public static async Task<(int ExitCode, string StdOut, string StdErr)> RunAsync(
8        string fileName,
9        string arguments)
10    {
11        var startInfo = new ProcessStartInfo
12        {
13            FileName = fileName,
14            Arguments = arguments,
15            RedirectStandardOutput = true,
16            RedirectStandardError = true,
17            UseShellExecute = false,
18            CreateNoWindow = true
19        };
20
21        using var process = new Process { StartInfo = startInfo };
22        process.Start();
23
24        Task<string> stdoutTask = process.StandardOutput.ReadToEndAsync();
25        Task<string> stderrTask = process.StandardError.ReadToEndAsync();
26
27        await process.WaitForExitAsync();
28
29        return (process.ExitCode, await stdoutTask, await stderrTask);
30    }
31}

This keeps the two streams moving and scales better when the child emits more data.

Decide Whether You Need Text, Lines, or Streaming

Not every command should be read into one big string. If the output is large or long-running, handle it line by line using OutputDataReceived and ErrorDataReceived. That lets your application react in real time and keeps memory use predictable.

Use full-string capture when:

  • Output is modest.
  • You need the entire content before processing.
  • The command is short-lived.

Use evented or streaming processing when:

  • Output is large.
  • The command runs continuously.
  • You want to log progress while the process is still running.

Choosing the right capture mode is part of the design. A short-lived CLI call and a long-running compiler or build tool do not have the same output handling needs.

Check Exit Codes, Not Just Output

A process can produce useful stdout and still fail. Always inspect ExitCode after the process exits. Many command-line tools report operational details on stdout and reserve stderr for diagnostics, but that is a convention, not a guarantee. The exit code is the real success signal.

You should also set the working directory and environment variables explicitly when the child process depends on them. Process execution bugs are often environment bugs, not API bugs.

Avoid Invoking a Shell Unnecessarily

If you want to run a specific executable with arguments, launch that executable directly. Starting cmd.exe or bash and then passing a command string increases quoting complexity and can create injection risks when user input is involved. Shell invocation is useful only when you explicitly need shell features such as pipes, wildcard expansion, or compound commands.

Common Pitfalls

  • Forgetting that UseShellExecute must be false for redirection.
  • Reading only stdout while stderr fills and blocks the child process.
  • Ignoring the child exit code and assuming output implies success.
  • Running through a shell when direct execution would be safer.
  • Failing to set the working directory or required environment variables.

Summary

  • Redirect stdout with UseShellExecute = false.
  • Redirect stderr too so failures are visible and stream deadlocks are less likely.
  • Use async reads when the child process may produce substantial output.
  • Check ExitCode after the process finishes.
  • Launch the target executable directly unless you truly need shell behavior.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.