Avatar ·

Как выполнить команды командной строки (CMD) из программы на C#?

Всем привет! Я новичок в C# и пишу небольшое приложение для автоматизации задач. Мне нужно, чтобы программа могла выполнять команды командной строки Windows, например, скопировать файлы с помощью `copy`, запустить `ping` или выполнить `ipconfig`. Я знаю, что можно просто открыть CMD и вводить команды вручную, но хочу, чтобы всё делалось автоматически из кода. Пробовал использовать `Process.Start("cmd.exe", "/c ping google.com")`, но ничего не происходит — окно командной строки мелькает и сразу закрывается, а результат я не вижу. Как мне передать команду, дождаться её выполнения и получить вывод (например, успешно ли выполнилась команда или текст из консоли)? Вот мой текущий код, который не работает: ```csharp Process.Start("cmd.exe", "/c ping google.com"); ``` Я слышал про `ProcessStartInfo` и `RedirectStandardOutput`, но запутался в настройках. Подскажите, пожалуйста, правильный способ. Нужно, чтобы программа могла выполнять как простые команды (вроде `dir`), так и более сложные с аргументами. Заранее спасибо! <<>>

Правильный способ выполнения команд CMD из C#

Ваша проблема в том, что вы запускаете процесс, но не ждёте его завершения и не перенаправляете вывод. Окно CMD действительно мелькает и закрывается, потому что процесс завершается сразу после выполнения команды. Чтобы получить результат, нужно использовать класс Process с правильной конфигурацией.

Вот полное и рабочее решение для выполнения любой команды и получения её вывода:

using System;
using System.Diagnostics;
using System.Text;

public static string RunCommand(string command)
{
    // Создаём настройки процесса
    ProcessStartInfo psi = new ProcessStartInfo
    {
        FileName = "cmd.exe",           // Запускаем CMD
        Arguments = $"/c {command}",    // /c выполняет команду и завершает CMD
        RedirectStandardOutput = true,  // Перенаправляем стандартный вывод
        RedirectStandardError = true,   // Перенаправляем вывод ошибок
        UseShellExecute = false,        // Отключаем оболочку Windows
        CreateNoWindow = true,          // Не показываем окно консоли
        StandardOutputEncoding = Encoding.UTF8, // Кодировка для русского текста
        StandardErrorEncoding = Encoding.UTF8
    };

    using (Process process = new Process { StartInfo = psi })
    {
        process.Start();

        // Читаем вывод и ошибки
        string output = process.StandardOutput.ReadToEnd();
        string error = process.StandardError.ReadToEnd();

        // Ждём завершения процесса
        process.WaitForExit();

        // Если есть ошибки, выбрасываем исключение
        if (!string.IsNullOrEmpty(error))
        {
            throw new Exception($"Ошибка выполнения команды: {error}");
        }

        return output;
    }
}

// Пример использования:
string result = RunCommand("ping google.com -n 1");
Console.WriteLine(result);

Ключевые моменты в коде:

  • FileName = "cmd.exe" — запускаем командную строку
  • Arguments = $"/c {command}" — флаг /c означает "выполнить команду и завершить"
  • RedirectStandardOutput = true — перенаправляем вывод, чтобы прочитать его в коде
  • UseShellExecute = false — обязательно для перенаправления потоков вывода
  • CreateNoWindow = true — скрываем чёрное окно CMD
  • process.WaitForExit() — ждём, пока команда выполнится

Асинхронный вариант (рекомендуется для GUI-приложений)

Если ваша программа имеет интерфейс (WPF, WinForms), лучше использовать асинхронный подход, чтобы не блокировать UI:

public static async Task<string> RunCommandAsync(string command)
{
    var tcs = new TaskCompletionSource<string>();
    var psi = new ProcessStartInfo
    {
        FileName = "cmd.exe",
        Arguments = $"/c {command}",
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        UseShellExecute = false,
        CreateNoWindow = true
    };

    var process = new Process { StartInfo = psi };
    var outputBuilder = new StringBuilder();
    var errorBuilder = new StringBuilder();

    process.OutputDataReceived += (sender, e) => outputBuilder.AppendLine(e.Data);
    process.ErrorDataReceived += (sender, e) => errorBuilder.AppendLine(e.Data);
    process.Exited += (sender, e) => tcs.TrySetResult(outputBuilder.ToString());

    process.Start();
    process.BeginOutputReadLine();
    process.BeginErrorReadLine();

    return await tcs.Task;
}

Дополнительные советы:

  • Для простых команд (например, ipconfig, dir) можно запускать их напрямую, без CMD: Process.Start("ipconfig.exe")
  • Если нужно выполнить несколько команд последовательно, используйте && в аргументах: "/c cd C:\\ && dir"
  • Для запуска от имени администратора добавьте psi.Verb = "runas"
  • Не забывайте обрабатывать исключения — команда может завершиться с ошибкой
<<>>

Альтернативный подход: использование PowerShell

Если вам нужно выполнять более сложные команды или скрипты, можно использовать PowerShell вместо CMD. PowerShell поддерживает все команды CMD и имеет гораздо больше возможностей, включая работу с объектами.

using System.Diagnostics;

public static string RunPowerShell(string command)
{
    var psi = new ProcessStartInfo
    {
        FileName = "powershell.exe",
        Arguments = $"-Command \"{command}\"",
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        UseShellExecute = false,
        CreateNoWindow = true
    };

    using (var process = new Process { StartInfo = psi })
    {
        process.Start();
        string output = process.StandardOutput.ReadToEnd();
        process.WaitForExit();
        return output;
    }
}

// Пример: выполнить команду CMD через PowerShell
string result = RunPowerShell("ipconfig /all");
Console.WriteLine(result);

Когда использовать PowerShell вместо CMD?

  • Когда нужно выполнить сложные скрипты с условиями и циклами
  • Когда требуется работа с WMI, реестром или файловой системой
  • Когда команда не работает через CMD (например, некоторые команды доступны только в PowerShell)

Недостаток: PowerShell запускается дольше, чем CMD, и требует больше ресурсов. Для простых команд лучше использовать первый вариант с cmd.exe.