C#
application development
.NET
process start
programming tips

Launching an application .EXE from C?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

In .NET, the standard way to launch another application is System.Diagnostics.Process. The main design choice is whether you want to simply open a program and return immediately, or start a process with controlled arguments, capture its output, and inspect the exit code.

The Basic Process.Start Call

For the simplest case, Process.Start is enough.

csharp
using System.Diagnostics;

Process.Start("notepad.exe");

If the executable is on the system path, this opens it. For a specific file on disk, use the full path.

csharp
using System.Diagnostics;

Process.Start(@"C:\Tools\MyApp.exe");

This is convenient, but it gives you very little control over quoting, arguments, or error handling.

Prefer ProcessStartInfo for Real Applications

For anything beyond a quick launch, use ProcessStartInfo.

csharp
1using System;
2using System.Diagnostics;
3
4var startInfo = new ProcessStartInfo
5{
6    FileName = @"C:\Tools\MyApp.exe",
7    Arguments = "--mode batch --input \"C:\\data\\file.txt\"",
8    UseShellExecute = false
9};
10
11Process process = Process.Start(startInfo);
12Console.WriteLine($"Started process id {process.Id}");

This approach is clearer and scales better when arguments become dynamic.

Opening a Document Versus Running an Executable

Sometimes you do not want to launch an .exe directly. You want Windows to open a file or URL with the default associated application.

In that case, use the shell:

csharp
1using System.Diagnostics;
2
3var startInfo = new ProcessStartInfo
4{
5    FileName = @"C:\reports\summary.pdf",
6    UseShellExecute = true
7};
8
9Process.Start(startInfo);

That tells Windows to open the file with the registered application rather than trying to execute the file itself.

Use the same pattern for URLs:

csharp
1using System.Diagnostics;
2
3var startInfo = new ProcessStartInfo
4{
5    FileName = "https://example.com",
6    UseShellExecute = true
7};
8
9Process.Start(startInfo);

Capture Output From a Console Program

If you need to read stdout or stderr, disable shell execution and redirect the streams.

csharp
1using System;
2using System.Diagnostics;
3
4var startInfo = new ProcessStartInfo
5{
6    FileName = "dotnet",
7    Arguments = "--info",
8    UseShellExecute = false,
9    RedirectStandardOutput = true,
10    RedirectStandardError = true,
11    CreateNoWindow = true
12};
13
14using var process = new Process { StartInfo = startInfo };
15process.Start();
16
17string stdout = process.StandardOutput.ReadToEnd();
18string stderr = process.StandardError.ReadToEnd();
19process.WaitForExit();
20
21Console.WriteLine(stdout);
22if (!string.IsNullOrWhiteSpace(stderr))
23{
24    Console.Error.WriteLine(stderr);
25}
26Console.WriteLine($"Exit code: {process.ExitCode}");

This is the pattern you want for automation, wrappers, and tooling.

Wait for Completion When the Result Matters

If your program depends on the launched process finishing first, call WaitForExit.

csharp
1using System.Diagnostics;
2
3using var process = Process.Start(new ProcessStartInfo
4{
5    FileName = "ping",
6    Arguments = "127.0.0.1 -n 2",
7    UseShellExecute = false
8});
9
10process.WaitForExit();

Without that call, your code continues immediately after starting the child process.

Build Arguments Safely

A common bug is manual string concatenation that breaks when paths contain spaces. In current .NET, ArgumentList is safer than building a single long string.

csharp
1using System.Diagnostics;
2
3var startInfo = new ProcessStartInfo
4{
5    FileName = @"C:\Tools\Importer.exe",
6    UseShellExecute = false
7};
8
9startInfo.ArgumentList.Add("--source");
10startInfo.ArgumentList.Add(@"C:\My Files\input.csv");
11startInfo.ArgumentList.Add("--verbose");
12
13Process.Start(startInfo);

This avoids many quoting errors and reduces risk when user input becomes part of the argument list.

Common Reasons Launching Fails

The usual exceptions are operational, not mysterious:

  • the path to the executable is wrong
  • the process lacks permission to access the file
  • you are trying to launch a GUI program from a service account that has no desktop session
  • the working directory is wrong for a dependency the target program expects

Set the working directory explicitly when needed:

csharp
1var startInfo = new ProcessStartInfo
2{
3    FileName = @"C:\Tools\MyApp.exe",
4    WorkingDirectory = @"C:\Tools",
5    UseShellExecute = false
6};

That matters for programs that load config files or DLLs relative to their startup folder.

Be Careful With User Input

If the executable path or arguments are influenced by a user, validate them carefully. Launching external processes is one of the easiest places to create injection problems or unsafe privilege boundaries.

A good default rule is:

  • keep the executable path fixed in code or config
  • pass user data only as validated arguments
  • prefer ArgumentList over hand-built command strings

A Good Default Pattern

For most .NET applications, this is a reasonable starting point:

csharp
1using System;
2using System.Diagnostics;
3
4var startInfo = new ProcessStartInfo
5{
6    FileName = @"C:\Tools\MyApp.exe",
7    UseShellExecute = false,
8    WorkingDirectory = @"C:\Tools"
9};
10
11startInfo.ArgumentList.Add("--job");
12startInfo.ArgumentList.Add("daily");
13
14using var process = Process.Start(startInfo);
15process.WaitForExit();
16Console.WriteLine(process.ExitCode);

It is explicit, testable, and easy to expand.

Common Pitfalls

Using Process.Start with a relative or incorrect path. Always verify the executable location.

Concatenating arguments into one fragile string when paths contain spaces. Prefer ArgumentList when available.

Trying to capture output while UseShellExecute is true. Redirection requires UseShellExecute = false.

Forgetting WaitForExit when you need the child process to finish before continuing.

Launching GUI applications from service or server contexts where no interactive desktop is available.

Summary

  • In C#, launch external programs with System.Diagnostics.Process.
  • Use the simple overload for quick starts and ProcessStartInfo for anything serious.
  • Turn off shell execution when you need output capture or fine-grained control.
  • Use ArgumentList or careful quoting for paths with spaces.
  • Check the executable path, working directory, and permissions before assuming the API is the problem.

Course illustration
Course illustration

All Rights Reserved.