C#
Process.start
Output
Programming
.NET

Process.start how to get the output?

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

To get output from a process in .NET, you must start it with redirected standard streams. The important settings are UseShellExecute = false and RedirectStandardOutput = true, and often RedirectStandardError = true as well.

The subtle part is avoiding deadlocks. Reading output incorrectly can block if the child process writes enough data to fill one stream while your code is waiting on the other.

The Minimum Working Setup

Here is a clean starting point:

csharp
1using System;
2using System.Diagnostics;
3using System.Threading.Tasks;
4
5static async Task Main()
6{
7    var startInfo = new ProcessStartInfo
8    {
9        FileName = "dotnet",
10        Arguments = "--info",
11        RedirectStandardOutput = true,
12        RedirectStandardError = true,
13        UseShellExecute = false,
14        CreateNoWindow = true
15    };
16
17    using var process = new Process { StartInfo = startInfo };
18    process.Start();
19
20    string stdout = await process.StandardOutput.ReadToEndAsync();
21    string stderr = await process.StandardError.ReadToEndAsync();
22    await process.WaitForExitAsync();
23
24    Console.WriteLine(stdout);
25    Console.WriteLine(stderr);
26}

That gives you the child process output as strings you can log, parse, or display.

Why UseShellExecute Must Be false

This setting is required for stream redirection:

csharp
UseShellExecute = false

If it stays true, the operating system shell owns the process launch path and .NET cannot redirect the standard streams the way you want.

This is one of the most common reasons "I set RedirectStandardOutput = true but got nothing" happens.

Capture Standard Error Too

If the process can write diagnostics or errors, redirect standard error as well:

csharp
RedirectStandardError = true

That matters because many command-line tools put useful information on stderr even when they succeed partly or fully. If you ignore stderr, you can miss the only clue about what went wrong.

Avoid Deadlocks by Reading Streams Properly

A naive pattern is:

csharp
string stdout = process.StandardOutput.ReadToEnd();
string stderr = process.StandardError.ReadToEnd();
process.WaitForExit();

This sometimes works, but it can deadlock if the child process fills one buffer while your code is blocked reading the other stream at the wrong time.

Asynchronous reading is safer for real tools that may write a lot of output:

csharp
1var stdoutTask = process.StandardOutput.ReadToEndAsync();
2var stderrTask = process.StandardError.ReadToEndAsync();
3
4await process.WaitForExitAsync();
5
6string stdout = await stdoutTask;
7string stderr = await stderrTask;

That pattern is much more robust.

Line-by-Line Processing

If you want output as it arrives rather than at the end, use event handlers:

csharp
1using System;
2using System.Diagnostics;
3
4var process = new Process();
5process.StartInfo = new ProcessStartInfo
6{
7    FileName = "dotnet",
8    Arguments = "--info",
9    RedirectStandardOutput = true,
10    RedirectStandardError = true,
11    UseShellExecute = false
12};
13
14process.OutputDataReceived += (_, e) =>
15{
16    if (e.Data is not null)
17        Console.WriteLine("OUT: " + e.Data);
18};
19
20process.ErrorDataReceived += (_, e) =>
21{
22    if (e.Data is not null)
23        Console.WriteLine("ERR: " + e.Data);
24};
25
26process.Start();
27process.BeginOutputReadLine();
28process.BeginErrorReadLine();
29await process.WaitForExitAsync();

This is useful for live logs, progress reporting, or long-running commands.

Exit Codes Matter Too

Output alone is not enough. Check the exit code:

csharp
1if (process.ExitCode != 0)
2{
3    Console.WriteLine($"Process failed with exit code {process.ExitCode}");
4}

A process may print something helpful and still fail, or print nothing and succeed. Treat output and exit status as separate signals.

Common Pitfalls

The biggest pitfall is forgetting UseShellExecute = false. Without it, redirection does not work.

Another common problem is reading stdout and stderr in a blocking way that can deadlock when the child process writes a lot of data.

People also forget that stderr is not the same as failure and stdout is not the same as success. You need the exit code too.

Finally, do not use Process.Start("some command with spaces") as a single raw string and hope the platform parses it the way you intended. Prefer FileName plus Arguments.

Summary

  • Redirect output with RedirectStandardOutput = true and UseShellExecute = false.
  • Redirect stderr as well if you care about diagnostics.
  • Prefer asynchronous or event-driven reading to avoid deadlocks.
  • Check the process exit code in addition to the output text.
  • Use structured ProcessStartInfo instead of relying on shell parsing.

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.