Вот фрагмент кода, который я написал несколько месяцев назад, чтобы решить аналогичную проблему. Я считаю, что инкапсулировать то, что я изучаю, в такой класс, более удобно, чем переучивать его в следующий раз, когда я столкнусь с подобной проблемой, но это очень просто / грубо / неполно. Я использовал несколько раз, пример использования ниже.
using System.Diagnostics;
// WIP: This class is incomplete in design and implementation.
/// <summary>
/// Wrapper class for running separate processes, and capturing/
/// redirecting their I/O.
/// </summary>
public class ShellExec
{
#region public
/// <summary>
/// The args to run Cmd with.
/// </summary>
public string Args { get; set; }
/// <summary>
/// The command to execute.
/// </summary>
public string Cmd { get; set; }
/// <summary>
/// The ProcessStartInfo used to execute the command.
/// </summary>
/// <remarks>
/// Initialized by the constructors. Can be modified before calling
/// RunSync() or RunAsync().
/// </remarks>
public ProcessStartInfo ProcessStartInfo { get; set; }
/// <summary>
/// The Process object used to execute the command.
/// </summary>
/// <remarks>
/// Initialized by the constructors. Can be modified before calling
/// RunSync() or RunAsync().
/// </remarks>
public Process Process { get; set; }
/// <summary>
/// The captured output from the last command execution.
/// </summary>
public string Result
{
get => _result;
}
/// <summary>
/// Run Cmd with Args, synchronously.
/// </summary>
/// <returns></returns>
public int RunSync()
{
Process.Start();
_result = Process.StandardOutput.ReadToEnd();
return Process.ExitCode;
}
#if false
/// <summary>
/// Run Cmd with Args, asynchronously.
/// </summary>
/// <returns></returns>
public void RunAsync()
{
return 0;
}
#endif
#region Constructors
/// <summary>
/// Simple constructor, uses our default ProcessStartInfo settings.
/// </summary>
/// <param name="cmd"></param>
/// <param name="args"></param>
public ShellExec(string cmd, string args)
{
var psi = new ProcessStartInfo(Cmd, Args)
{
RedirectStandardOutput = true, // Capture output.
UseShellExecute = false, // No graphical shell.
CreateNoWindow = true // Execute in background (no window).
};
Initialize(cmd, args, psi);
}
#endregion Constructors
#endregion public
#region private
private string _result;
private void Initialize(string cmd, string args, ProcessStartInfo psi)
{
psi.FileName = Cmd = cmd;
psi.Arguments = Args = args;
ProcessStartInfo = psi;
Process = new Process
{
StartInfo = ProcessStartInfo
};
}
// Hide default constructor.
private ShellExec() {}
#endregion private
}
Использование:
ShellExec se = new ShellExec("cmd.exe", "/c dir");
int exitCode = se.RunSync();
Console.WriteLine(se.Result);