using System.Diagnostics; public static class CommandRunner { public static async Task RunAsync(string command, string workingDir, Action onStdout, Action onStderr) { var psi = new ProcessStartInfo { FileName = GetShell(), RedirectStandardInput = true, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, WorkingDirectory = workingDir }; var process = new Process { StartInfo = psi }; process.OutputDataReceived += (_, e) => { if (e.Data != null) onStdout(e.Data); }; process.ErrorDataReceived += (_, e) => { if (e.Data != null) onStderr(e.Data); }; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); // Write the command to stdin and close it await process.StandardInput.WriteLineAsync(command); await process.StandardInput.WriteLineAsync("exit $?"); // Exit with the command's exit code process.StandardInput.Close(); await process.WaitForExitAsync(); return process.ExitCode; } private static string GetShell() { return OperatingSystem.IsWindows() ? "cmd.exe" : "/bin/bash"; } }