Запустіть командні рядки команд


605

Чи є спосіб запускати команди командних рядків із додатку C #? Якщо так, як би я зробив наступне:

copy /b Image1.jpg + Archive.rar Image2.jpg

Це в основному вбудовує файл RAR у зображення JPG. Мені було просто цікаво, чи є спосіб зробити це автоматично в C #.


6
Дублікат stackoverflow.com/questions/181719/… (там є відповідь, яка робить те, що ви хочете).
Метт Гамільтон

stackoverflow.com/a/5367686/492 має кращу відповідь
CAD блокується

Відповіді:


917

це все, що вам потрібно зробити, запустити команди оболонки з C #

string strCmdText;
strCmdText= "/C copy /b Image1.jpg + Archive.rar Image2.jpg";
System.Diagnostics.Process.Start("CMD.exe",strCmdText);

Редагувати:

Це потрібно, щоб приховати вікно cmd.

System.Diagnostics.Process process = new System.Diagnostics.Process();
System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
startInfo.FileName = "cmd.exe";
startInfo.Arguments = "/C copy /b Image1.jpg + Archive.rar Image2.jpg";
process.StartInfo = startInfo;
process.Start();

РЕДАКТ: 2

Важливо те, що аргумент починається з /Cіншого, він не працюватиме. Як сказав Скотт Фергюсон : "Виконує команду, задану рядком, а потім припиняє".


166
/ C Виконує команду, задану рядком, а потім припиняє
Скотт Фергюсон,

16
просто сказати cmd запустити та припинити (не чекайте, коли будь-який вхід користувача закриє вікно)
RameshVel

3
Дякую, ще одне питання. Чи є спосіб приховати командний рядок під час цього?
користувач

9
Я не бачу, як я єдиний, хто вважає це жахливою ідеєю. Так, це спрацює, але це абсолютно і зовсім неправильно. Нерестування CMD-процесів для виконання простих операцій вводу-виводу є неправильним, навіть якщо це працює. Прочитайте документацію в просторі імен System.IO. Тут є більш ніж достатньо функціональних можливостей, щоб робити те, що вам потрібно зробити, не створюючи непотрібних процесів.
Мисливець на екземпляри

56
FYI: Використовуйте process.WaitForExit (), щоб дочекатися завершення процесу, перш ніж продовжувати і обробляти.ExitCode, щоб отримати вихідний код процесу.
шиндиго

122

Спробував рішення @RameshVel, але я не міг передати аргументи у своїй консольній програмі. Якщо хтось відчуває ту саму проблему, тут є рішення:

using System.Diagnostics;

Process cmd = new Process();
cmd.StartInfo.FileName = "cmd.exe";
cmd.StartInfo.RedirectStandardInput = true;
cmd.StartInfo.RedirectStandardOutput = true;
cmd.StartInfo.CreateNoWindow = true;
cmd.StartInfo.UseShellExecute = false;
cmd.Start();

cmd.StandardInput.WriteLine("echo Oscar");
cmd.StandardInput.Flush();
cmd.StandardInput.Close();
cmd.WaitForExit();
Console.WriteLine(cmd.StandardOutput.ReadToEnd());

2
добре, я не давав шансів думати, що на моїй машині є деякі обмеження адміністратора чи антивірусу, але .. код вище працює! дякую Огглас
Піт Козак

6
цей рядок: cmd.StartInfo.CreateNoWindow = true; врятував мені день.
Ганеш Камат - 'Код несамовитості'

Чи є спосіб виконання декількох команд в одномуcmd.StandardInput.WriteLine(@"cd C:\Test; pwd")
Зах Сміт

36
var proc1 = new ProcessStartInfo();
string anyCommand; 
proc1.UseShellExecute = true;

proc1.WorkingDirectory = @"C:\Windows\System32";

proc1.FileName = @"C:\Windows\System32\cmd.exe";
proc1.Verb = "runas";
proc1.Arguments = "/c "+anyCommand;
proc1.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(proc1);

2
Який @знак у C #?
Pacerier

6
@Pacerier Вказує компілятору уникнути всіх символів, які, як правило, повинні бути використані в рядку, в цьому випадку \. Отже, без \ ваш код виглядав биproc1.FileName = "C:\\Windows\\System32\\cmd.exe";
Джеймс Ко

1
Слід зазначити, що proc1.Verb = "runas";змушує цей процес працювати з підвищеними привілеями ... Це не завжди призначено.
Діней

1
Як зробити так, щоб це вікно cmd не закривалося після його закінчення?
Хрвой Т

1
Я виявив, що виклик "cd path", з'єднаний "&&" з іншими командами у рядку, завжди виконується останнім, навіть якщо він пройшов перший. your: 'proc1.WorkingDirectory = @ "C: \ Windows \ System32";' було дуже корисно! Дякую!
Нозим Туракулов

11

Жоден із вищезазначених відповідей чомусь не допоміг. Схоже, вони підмивають помилки під килим і ускладнюють усунення несправностей. Тож я закінчила щось подібне, можливо, це допоможе комусь іншому:

var proc = new Process
{
    StartInfo = new ProcessStartInfo
    {
        FileName = @"C:\Program Files\Microsoft Visual Studio 14.0\Common7\IDE\tf.exe",
        Arguments = "checkout AndroidManifest.xml",
        UseShellExecute = false,
        RedirectStandardOutput = true,
        CreateNoWindow = true,
        WorkingDirectory = @"C:\MyAndroidApp\"
    }
};

proc.Start();

Якщо я хочу скомпілювати це в окрему консольну програму, який ще код потрібно буде додати, щоб він працював? (Я noob для всіх цих програм програмування, тільки деякі сценарії). Я використовую csc.exe btw.
script'n'code

@copyitright Простір імен та клас. Якщо ви просто створите новий проект, він буде створений для вас.
coinbird

Ага. не звертай уваги. якщо ви використовуєте cmd.exeдодаток, ви можете передавати команди як аргументи.
Зак Сміт

Для нащадків: я хотів, щоб процес запустився echo Hello World!і відобразив командний висновок у вікні cmd, яке спливе. Так що я пробував: Filename = @"echo", Arguments = "Hello World!", UseShellExecute = false, RedirectStandardOuput = false, CreateNoWindow = false. Це дозволило у вікні cmd батьківської програми відображати "Hello World!" (що має сенс, оскільки stdout не був перенаправлений на дочірній процес).
Мінь Тран

10

Хоча технічно це не відповідає безпосередньо на поставлене запитання, воно відповідає на питання, як зробити те, що хотів зробити оригінальний плакат: комбінувати файли. Якщо що, це повідомлення, яке допоможе новачкам зрозуміти, про що говорять про Інстанцію Мисливця та Костянтина.

Це метод, який я використовую для комбінування файлів (у цьому випадку jpg та zip). Зауважте, що я створюю буфер, який заповнюється вмістом zip-файлу (невеликими шматками, а не однією великою операцією читання), а потім буфер записується на задню частину jpg-файлу до кінця zip-файлу. досяг:

private void CombineFiles(string jpgFileName, string zipFileName)
{
    using (Stream original = new FileStream(jpgFileName, FileMode.Append))
    {
        using (Stream extra = new FileStream(zipFileName, FileMode.Open, FileAccess.Read))
        {
            var buffer = new byte[32 * 1024];

            int blockSize;
            while ((blockSize = extra.Read(buffer, 0, buffer.Length)) > 0)
            {
                original.Write(buffer, 0, blockSize);
            }
        }
    }
}

9

якщо ви хочете залишати вікно cmd відкритим або хочете використовувати його у winform / wpf, тоді використовуйте його так

    string strCmdText;
//For Testing
    strCmdText= "/K ipconfig";

 System.Diagnostics.Process.Start("CMD.exe",strCmdText);

/ К

Зберігатиме вікно cmd відкритим


Приємно. Знайшла цю документацію для cmdкоманди та її параметрів.
пій

8

Так, є (див. Посилання в коментарі Метта Гамілтона), але було б простіше і краще використовувати класи IO. IO. Ви можете використовувати File.ReadAllBytes для читання файлів, а потім File.WriteAllBytes для написання "вбудованої" версії.


11
Завантаження цілих файлів у пам'ять просто для додавання один до іншого не дуже ефективно, особливо якщо файли досить великі.
Костянтин Спірін

7
Спробуйте поглянути на дух відповіді. Справа в тому, що .NET має більш ніж достатньо класів IO і функцій для цього, не вимагаючи викликати оболонку ОС. Конкретні функції, про які я згадував, можуть бути не найкращими, але вони були просто найпростішими. Немає сенсу взагалі викликати оболонку для цього.
Мисливець на екземпляр

7

Це можна зробити за допомогою CliWrap в одному рядку:

var stdout = new Cli("cmd")
         .Execute("copy /b Image1.jpg + Archive.rar Image2.jpg")
         .StandardOutput;

Я підтримав це ... але, схоже, репо вже не вистачає:Unable to find package 'CliWrap' at source
Зах Сміт

1
@ZachSmith не впевнений, що ти маєш на увазі, nuget.org/packages/CliWrap, здається, працює добре. Оригінальне посилання теж.
Тиррз

Ah.sorry .. з якоїсь причини, коли я не зміг підключитися до свого nuget repo через vpn, мені не вдалося встановити цей пакет. nuget все ще для мене загадка. напевно, це було встановлено неправильно
Зак Сміт


5

Ось невелика проста і менш кодова версія. Це також приховає вікно консолі -

System.Diagnostics.Process process = new System.Diagnostics.Process();
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.Arguments = "/C copy /b Image1.jpg + Archive.rar Image2.jpg";
process.Start();

5

якщо ви хочете виконати команду в режимі асинхронізації - і надрукуйте результати. Ви можете цей клас:

    public static class ExecuteCmd
{
    /// <summary>
    /// Executes a shell command synchronously.
    /// </summary>
    /// <param name="command">string command</param>
    /// <returns>string, as output of the command.</returns>
    public static void ExecuteCommandSync(object command)
    {
        try
        {
            // create the ProcessStartInfo using "cmd" as the program to be run, and "/c " as the parameters.
            // Incidentally, /c tells cmd that we want it to execute the command that follows, and then exit.
            System.Diagnostics.ProcessStartInfo procStartInfo = new System.Diagnostics.ProcessStartInfo("cmd", "/c " + command);
            // The following commands are needed to redirect the standard output. 
            //This means that it will be redirected to the Process.StandardOutput StreamReader.
            procStartInfo.RedirectStandardOutput =  true;
            procStartInfo.UseShellExecute = false;
            // Do not create the black window.
            procStartInfo.CreateNoWindow = true;
            // Now we create a process, assign its ProcessStartInfo and start it
            System.Diagnostics.Process proc = new System.Diagnostics.Process();
            proc.StartInfo = procStartInfo;
            proc.Start();

            // Get the output into a string
            string result = proc.StandardOutput.ReadToEnd();

            // Display the command output.
            Console.WriteLine(result);
        }
        catch (Exception objException)
        {
            // Log the exception
            Console.WriteLine("ExecuteCommandSync failed" + objException.Message);
        }
    }

    /// <summary>
    /// Execute the command Asynchronously.
    /// </summary>
    /// <param name="command">string command.</param>
    public static void ExecuteCommandAsync(string command)
    {
        try
        {
            //Asynchronously start the Thread to process the Execute command request.
            Thread objThread = new Thread(new ParameterizedThreadStart(ExecuteCommandSync));
            //Make the thread as background thread.
            objThread.IsBackground = true;
            //Set the Priority of the thread.
            objThread.Priority = ThreadPriority.AboveNormal;
            //Start the thread.
            objThread.Start(command);
        }
        catch (ThreadStartException )
        {
            // Log the exception
        }
        catch (ThreadAbortException )
        {
            // Log the exception
        }
        catch (Exception )
        {
            // Log the exception
        }
    }

}

2

Ви можете досягти цього, використовуючи наступний метод (як зазначено в інших відповідях):

strCmdText = "'/C some command";
Process.Start("CMD.exe", strCmdText);

Коли я спробував перераховані вище методи, я виявив, що моя власна команда не працює, використовуючи синтаксис деяких відповідей вище.

Я з'ясував, що більш складні команди потрібно інкапсулювати в лапки, щоб працювати:

string strCmdText;
strCmdText = "'/C cd " + path + " && composer update && composer install -o'";
Process.Start("CMD.exe", strCmdText);

1

ви можете використовувати просто записати код у .batрозширення формату, код пакетного файлу:

c:/ copy /b Image1.jpg + Archive.rar Image2.jpg

використовувати цей c # код:

Process.Start("file_name.bat")


якщо ви хочете приховати cmd під час запуску, ви можете використовувати простий візуальний базовий код скрипту в .vbsрозширенні формату, код:CreateObject("Wscript.Shell").Run "filename.bat",0,True
XMMR12
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.