How to run commands in command prompt using C#

By FoxLearn 1/17/2025 7:18:47 AM   107
To run CMD commands in C#, you can utilize the `System.Diagnostics.Process` class.

To run a CMD command, follow these steps:

  1. Instantiate a new Process object.
  2. Set the StartInfo.FileName property to the path of the CMD executable.
  3. Set the StartInfo.Arguments property to the CMD command you wish to run.
  4. Invoke the Start() method to launch the process.
  5. Wait for the process to complete by calling the WaitForExit() method.
  6. Retrieve the process output from the StandardOutput property.

How to execute a cmd command in C#?

using System;
using System.Diagnostics;

public class Program
{
    public static void Main()
    {
        // Initialize a new Process object.
        Process process = new Process();
        
        // Set the FileName to the CMD executable path.
        process.StartInfo.FileName = "cmd.exe";
        
        // Specify the CMD command to execute.
        process.StartInfo.Arguments = "/c dir";
        
        // Start the process.
        process.Start();
        
        // Wait for the process to complete.
        process.WaitForExit();
        
        // Retrieve the output from the process.
        string output = process.StandardOutput.ReadToEnd();
        
        // Print the process output.
        Console.WriteLine(output);
    }
}

The Process class can also be used to run CMD commands in the background. To achieve this, set the StartInfo.CreateNoWindow property to true, which will prevent the CMD window from appearing during execution.

How to execute a CMD command in the background in C#

using System;
using System.Diagnostics;

public class Program
{
    public static void Main()
    {
        // Initialize a new Process object.
        Process process = new Process();
        
        // Set the FileName to the CMD executable path.
        process.StartInfo.FileName = "cmd.exe";
        
        // Specify the CMD command to execute.
        process.StartInfo.Arguments = "/c dir";
        
        // Prevent the CMD window from being displayed.
        process.StartInfo.CreateNoWindow = true;
        
        // Start the process.
        process.Start();
    }
}

The Process class allows you to execute any CMD command, which can be helpful for automating tasks or running commands that need administrator privileges.

How to execute multiple commands in cmd using C#?

Next, we need a method to run the file in CMD.

First, we will create a method to execute it in a separate process. Then, we will load this method asynchronously using a thread within the current program process.

using System;
using System.Diagnostics;
using System.IO;
using System.Threading;

public class Program
{
    // Method to write content to a file
    private void WriteContentToFile(string cmdFileName, string[] lines)
    {
        while (IsFileLocked(new FileInfo(cmdFileName)))
        {
            // Wait until the file is not locked.
        }

        string content = string.Join("\n", lines);
        File.WriteAllText(cmdFileName, content);
    }

    // Method to check if the file is locked
    private bool IsFileLocked(FileInfo file)
    {
        try
        {
            using (FileStream stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None))
            {
                // If we can open the file without any exception, it is not locked
                return false;
            }
        }
        catch (IOException)
        {
            // If an IOException occurs, it means the file is locked
            return true;
        }
    }

    // Method to execute the file in a separate process
    private void ExecuteFileInProcess(string cmdFileName)
    {
        Process process = new Process();
        process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.Arguments = "/c " + cmdFileName; // Execute the CMD file
        process.StartInfo.CreateNoWindow = true; // Prevent showing the command window
        process.Start();
        process.WaitForExit();
    }

    // Asynchronous method to run the process using a thread
    public void ExecuteFileAsync(string cmdFileName)
    {
        // Start a new thread to execute the file in the background
        Thread executeThread = new Thread(() => ExecuteFileInProcess(cmdFileName));
        executeThread.Start();
    }

    public static void Main()
    {
        Program program = new Program();

        // Example usage
        string fileName = "example.cmd";
        string[] lines = new string[] { "echo Hello, World!", "dir" };

        // Write content to file
        program.WriteContentToFile(fileName, lines);

        // Execute the file asynchronously
        program.ExecuteFileAsync(fileName);

        // Optionally, you can wait for the thread to complete (e.g., if you need to wait for the process)
        // executeThread.Join();
    }
}

To run multiple command you can write like this.

public void RunMultiLineCommand()
{
    char quoteChar = '"';
    string[] cmdArr = new string[] 
    {
        "cd /", 
        "C:", 
        "dir", 
        string.Format("cd {0}Program Files{0}", quoteChar), 
        "dir", 
        "pause"
    };
    
    string fileName = System.AppDomain.CurrentDomain.BaseDirectory + "testcmd.cmd";
    
    // Write the commands to the file
    WriteContentToFile(fileName, cmdArr);
    
    // Create and start a background thread to execute the CMD script
    Thread cmdThread = new Thread(new ParameterizedThreadStart(RunCMDScript))
    {
        IsBackground = true,
        Priority = ThreadPriority.AboveNormal
    };
    
    cmdThread.Start(fileName);
}

When using Process in C# to call cmd.exe, a common issue arises: the process may hang during execution.

Pass Arguments During Process Creation

The following snippet shows how to pass arguments at the time of process creation:

var processInfo = new ProcessStartInfo("cmd.exe", "/c systeminfo")
{
    CreateNoWindow = true,
    UseShellExecute = false,
    RedirectStandardError = true,
    RedirectStandardOutput = true,
    WorkingDirectory = @"C:\Windows\System32\"
};

StringBuilder sb = new StringBuilder();
Process p = Process.Start(processInfo);
p.OutputDataReceived += (sender, args) => sb.AppendLine(args.Data);
p.BeginOutputReadLine();
p.WaitForExit();
Console.WriteLine(sb.ToString());

This approach requires input arguments to be specified during process creation, which may not always be feasible.

A more flexible solution is to redirect StandardInput and StandardOutput.

Building a Custom Command Execution Service

First, define the necessary fields for managing the process and synchronizing output:

private Process _cmdProcess;
private StreamWriter _streamWriter;
private AutoResetEvent _outputWaitHandle;
private string _cmdOutput;

Create an instance of ProcessStartInfo and configure it to redirect input and output streams:

ProcessStartInfo processStartInfo = new ProcessStartInfo
{
    FileName = "cmd.exe",
    UseShellExecute = false,
    RedirectStandardOutput = true,
    RedirectStandardInput = true,
    CreateNoWindow = true
};

_cmdProcess = new Process { StartInfo = processStartInfo };
_cmdProcess.OutputDataReceived += _cmdProcess_OutputDataReceived;

Start the process with asynchronous output reading:

_cmdProcess.Start();
_cmdProcess.BeginOutputReadLine();

Define a method to execute commands and handle output synchronization:

public string ExecuteCommand(string command)
{
    _cmdOutput = string.Empty;
    
    _streamWriter.WriteLine(command);
    _streamWriter.WriteLine("echo end");
    _outputWaitHandle.WaitOne();
    
    return _cmdOutput;
}

Handle the OutputDataReceived event to accumulate output:

private void _cmdProcess_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
    if (e.Data == null || e.Data == "end")
    {
        _outputWaitHandle.Set();
    }
    else
    {
        _cmdOutput += e.Data + Environment.NewLine;
    }
}

Use the custom command service to execute Command Prompt commands interactively:

using (CmdService cmdService = new CmdService("cmd.exe"))
{
    string consoleCommand;
    do
    {
        consoleCommand = Console.ReadLine();
        string output = cmdService.ExecuteCommand(consoleCommand);
        Console.WriteLine($">>> {output}");
    }
    while (!string.IsNullOrEmpty(consoleCommand));
}

Command Execution

Echo Command

echo Hello

Output:

Hello
end

Directory Listing

dir

Output: Displays the directory contents followed by end.

Anaconda Commands

conda env list
activate Python3

After activating an environment, you can execute Python scripts:

print("Hello from Python")

With this implementation, you can execute Command Prompt commands dynamically from C#.