This content originally appeared on DEV Community and was authored by Emanuele Bartolesi
Ever needed your C# application to run a PowerShell script, wait until it's done, and print the output directly in your console?
Maybe you're automating a deployment process, launching a diagnostic script, or integrating with a CLI tool like Git, Docker, or ffmpeg.
After a few years, in these days, I had to do it again and I think I found the right way again, because I forgot how to do it! 😀
Let’s dive in.
🚀 Why Execute External Commands from C#?
Running external commands from a C# application is more common than you might think. In many real-world scenarios, you don’t want to reimplement logic that already exists in command-line tools or scripts.
Here are a few examples where this is useful:
- 💪 Automation & DevOps: Running PowerShell scripts for provisioning resources, deploying software, or managing files.
- 🐳 Tool Integration: Calling
docker
,git
,az
, orffmpeg
to leverage existing CLI workflows inside your app. - 📄 Legacy Compatibility: Executing older batch or shell scripts without rewriting them in C#.
- 📦 Hybrid Workflows: Combining the power of .NET with external tools to create flexible automation pipelines.
Tip: While it's easy to start a process, doing it right — especially handling output and waiting for completion — requires some care. That’s exactly what I will cover next.
⚙️ Setting Up the Project
To follow along, you’ll need a basic .NET console application. Here's how to get started:
🛠️ Prerequisites
- .NET SDK (I use .NET 9 but from .NET 6 is more or less the same)
- PowerShell (included on Windows by default)
- An IDE like Visual Studio, JetBrains Rider, or just your favorite code editor and terminal
📦 Creating the Project
In your terminal:
dotnet new console -n ConsoleWaitScript
cd ConsoleWaitScript
This scaffolds a simple C# console app with a Program.cs
file.
Next, replace the contents of Program.cs
with the following code.
I'll break it down in detail in the next section.
🧪 The Inline PowerShell Example
Let’s dive into the heart of the project — running an inline PowerShell script from C# and waiting for it to complete.
Here’s the full code:
using System;
using System.Diagnostics;
namespace ConsoleWaitScript
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("PowerShell Script Launcher");
for (int i = 0; i < 10; i++)
{
RunInlineCountdownScript(10);
}
}
static void RunInlineCountdownScript(int seconds)
{
Console.WriteLine($"Running inline PowerShell countdown script for {seconds} seconds");
string inlineScript = $@"
Write-Host 'Starting countdown for {seconds} seconds'
for ($i = {seconds}; $i -gt 0; $i--) {{
Write-Host \"$i seconds remaining...\"
Start-Sleep -Seconds 1
}}
Write-Host 'Countdown complete!'
";
try
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = "powershell.exe",
Arguments = $"-ExecutionPolicy Bypass -Command \"{inlineScript}\"",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = false
};
using (Process process = new Process())
{
process.StartInfo = startInfo;
process.OutputDataReceived += (sender, e) =>
{
if (!string.IsNullOrEmpty(e.Data))
Console.WriteLine(e.Data);
};
process.ErrorDataReceived += (sender, e) =>
{
if (!string.IsNullOrEmpty(e.Data))
Console.WriteLine($"ERROR: {e.Data}");
};
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
process.WaitForExit();
Console.WriteLine($"Script completed with exit code: {process.ExitCode}");
}
}
catch (Exception ex)
{
Console.WriteLine($"Error executing PowerShell script: {ex.Message}");
}
}
}
}
🔍 What’s Happening Here?
- I defined a PowerShell script inline, using string interpolation to build the countdown logic dynamically.
-
ProcessStartInfo
configures how the process will run:-
UseShellExecute = false
: needed to redirect output. -
RedirectStandardOutput
andRedirectStandardError
: lets us capture and log what the script prints. -
CreateNoWindow = false
: allows you to see the script’s window, if one opens.
-
We hook into
OutputDataReceived
andErrorDataReceived
to print live output from PowerShell.WaitForExit()
makes sure our app waits for the script to finish before continuing.
Note: This pattern works for any executable, not just PowerShell!
📦 Tips
🔒 UseShellExecute = false
Setting this to false
is essential when you want to redirect output or error streams.
⏹️ Always Wait for Completion
Without process.WaitForExit()
, your application may exit or continue before the external command finishes.
📤 Flush Output with BeginOutputReadLine
Using this ensures output is processed line-by-line and doesn't hang waiting for the full buffer.
💡 Escape Carefully
If your script gets complex, consider writing it to a .ps1
file instead of embedding it.
⚠️ About -ExecutionPolicy Bypass
Use with care, especially in production.
📌 Real-World Use Cases
🐙 Git Automation
For instance, this is my case. I have to wait a long operation, based on git.
startInfo.FileName = "git";
startInfo.Arguments = "clone https://github.com/user/repo.git";
🐳 Running Docker or CLI Tools
startInfo.FileName = "docker";
startInfo.Arguments = "run --rm hello-world";
🛠 DevOps Script Orchestration
Use with database backups, codegen, secret rotation, etc.
🧪 Test Harnesses
Great for running test runners or diagnostic tools.
🔖 Stay ahead of the dev curve
I created a Curated RSS Feed Bundle for Web Developers — a hand-picked OPML file of the best dev blogs and websites on the internet.
💡 Just download, import into your favorite RSS reader (like Feedly or NetNewsWire), and enjoy fresh insights every day.
👉 Grab it on Gumroad — stay sharp without the noise.
This content originally appeared on DEV Community and was authored by Emanuele Bartolesi

Emanuele Bartolesi | Sciencx (2025-06-28T18:29:50+00:00) Running External Commands in C# and Wait Until They Finish. Retrieved from https://www.scien.cx/2025/06/28/running-external-commands-in-c-and-wait-until-they-finish/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.