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


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.