Esegui comandi prompt dei comandi


605

Esiste un modo per eseguire i comandi del prompt dei comandi dall'interno di un'applicazione C #? In tal caso, come farei quanto segue:

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

Questo fondamentalmente incorpora un file RAR nell'immagine JPG. Mi stavo solo chiedendo se ci fosse un modo per farlo automaticamente in C #.


6
Duplica di stackoverflow.com/questions/181719/… (c'è una risposta lì che fa quello che vuoi).
Matt Hamilton,

stackoverflow.com/a/5367686/492 ha una risposta migliore
Bloke CAD

Risposte:


918

questo è tutto ciò che devi fare per eseguire comandi shell da C #

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

MODIFICARE:

Questo serve a nascondere la finestra 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();

MODIFICA: 2

Importante è che l'argomento inizi con /Caltrimenti non funzionerà. Come ha detto Scott Ferguson : "Esegue il comando specificato dalla stringa e quindi termina".


166
/ C Esegue il comando specificato dalla stringa e quindi termina
Scott Ferguson,

16
è solo per dire al cmd di funzionare e terminare (non aspettare che nessun input dell'utente chiuda la finestra)
RameshVel

3
Grazie, un'altra domanda. C'è un modo per nascondere il prompt dei comandi durante questo?
utente

9
Non vedo come sono l'unico a pensare che sia un'idea orribile. Sì, funzionerà, ma è completamente e totalmente sbagliato. La generazione di processi CMD per eseguire semplici operazioni di I / O è errata, anche se funziona. Leggi la documentazione sullo spazio dei nomi System.IO. C'è funzionalità più che sufficiente lì dentro per fare ciò che devi fare senza generare processi non necessari.
Instance Hunter,

56
FYI: utilizzare process.WaitForExit () per attendere il completamento del processo prima di continuare e process.ExitCode per ottenere il codice di uscita del processo.
shindigo,

122

Ho provato la soluzione @RameshVel ma non sono riuscito a passare argomenti nella mia applicazione console. Se qualcuno ha lo stesso problema, ecco una soluzione:

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
bene non ho dato alcuna possibilità pensando che sulla mia macchina ci siano alcune restrizioni di amministrazione o antivirus ma .. il codice sopra funziona! grazie Ogglas
Pete Kozak il

6
questa riga: cmd.StartInfo.CreateNoWindow = true; mi ha salvato la giornata.
Ganesh Kamath - "Code Frenzy",

Esiste un modo per eseguire più comandi in un singolocmd.StandardInput.WriteLine(@"cd C:\Test; pwd")
Zach Smith,

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
Qual è il @segno in C #?
Pacerier

6
@Pacerier Indica al compilatore di sfuggire a tutti i caratteri che normalmente dovrebbero essere salvati nella stringa, in questo caso \. Quindi, senza il \, il tuo codice sarebbe simileproc1.FileName = "C:\\Windows\\System32\\cmd.exe";
James Ko

1
Va notato che proc1.Verb = "runas";questo processo viene eseguito con privilegi elevati ... Questo non è sempre inteso.
Dinei,

1
Come posso fare per chiudere questa finestra cmd al termine?
Hrvoje T,

1
Ho scoperto che chiamare 'cd path' unito da '&&' con altri comandi nella riga viene sempre eseguito per ultimo anche se è andato per primo. tuo: 'proc1.WorkingDirectory = @ "C: \ Windows \ System32";' è stato molto utile! Grazie!
Nozim Turakulov,

11

Nessuna delle risposte di cui sopra ha aiutato per qualche motivo, sembra che spazzino gli errori sotto il tappeto e rendano difficile la risoluzione dei problemi del comando. Quindi ho finito con qualcosa del genere, forse aiuterà qualcun altro:

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();

Se volessi compilarlo in un'applicazione console autonoma, quale altro codice dovrebbe essere aggiunto per farlo funzionare? (Sono un noob per tutte queste cose di programmazione, ho fatto solo alcuni script). Sto usando csc.exe a proposito.
script'n'code

@copyitright Uno spazio dei nomi e una classe. Se crei un nuovo progetto, questi verranno generati per te.
coinbird

Ah. non importa. se usi l' cmd.exeapp puoi passare comandi come argomenti.
Zach Smith,

Per i posteri: volevo che il processo fosse eseguito echo Hello World!e visualizzare l'output del comando nella finestra cmd che si apre. Così ho provato: Filename = @"echo", Arguments = "Hello World!", UseShellExecute = false, RedirectStandardOuput = false, CreateNoWindow = false. Ciò ha consentito alla finestra cmd dell'applicazione padre di visualizzare "Hello World!" (il che ha senso perché stdout non è stato reindirizzato al processo figlio).
Minh Tran,

10

Sebbene tecnicamente questo non risponda direttamente alla domanda posta, risponde alla domanda su come fare ciò che il poster originale voleva fare: combinare i file. Semmai, questo è un post per aiutare i neofiti a capire di cosa parlano Instance Hunter e Konstantin.

Questo è il metodo che uso per combinare i file (in questo caso un jpg e uno zip). Si noti che creo un buffer che viene riempito con il contenuto del file zip (in piccoli blocchi piuttosto che in una grande operazione di lettura), quindi il buffer viene scritto sul retro del file jpg fino alla fine del file zip raggiunto:

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

se vuoi tenere aperta la finestra cmd o vuoi usarla in winform / wpf, usala in questo modo

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

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

/K

Manterrà aperta la finestra cmd


Bello. Ho trovato questa documentazione per il cmdcomando e i suoi parametri.
Pio

8

Sì, c'è (vedi link nel commento di Matt Hamilton), ma sarebbe più facile e migliore usare le classi IO di .NET. È possibile utilizzare File.ReadAllBytes per leggere i file e quindi File.WriteAllBytes per scrivere la versione "incorporata".


11
Il caricamento di interi file in memoria solo per aggiungersi l'uno all'altro non è molto efficiente, specialmente se i file sono abbastanza grandi.
Konstantin Spirin,

7
Prova a guardare lo spirito della risposta. Il punto è che .NET ha più che sufficienti classi e funzioni IO per fare ciò senza dover chiamare la shell del sistema operativo. Le funzioni particolari che ho citato potrebbero non essere le migliori, ma quelle erano solo le più semplici. Non ha alcun senso chiamare la shell per farlo.
Instance Hunter,

7

Puoi farlo usando CliWrap in una riga:

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

Ho votato a favore di questo ... ma il repo sembra mancare ora:Unable to find package 'CliWrap' at source
Zach Smith,

1
@ZachSmith non è sicuro di cosa intendi, nuget.org/packages/CliWrap sembra funzionare bene. Anche il link originale.
Tyrrrz,

Ah.sorry .. per qualche motivo quando non sono riuscito a connettermi al mio repository nuget su VPN non sono stato in grado di installare questo pacchetto. nuget è ancora per lo più un mistero per me. deve averlo impostato male
Zach Smith,


5

Ecco una versione poco semplice e meno in codice. Nasconderà anche la finestra della console-

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

se si desidera eseguire il comando in modalità asincrona - e stampare i risultati. puoi questa classe:

    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

È possibile ottenere ciò utilizzando il seguente metodo (come indicato in altre risposte):

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

Quando ho provato i metodi sopra elencati ho scoperto che il mio comando personalizzato non funzionava usando la sintassi di alcune delle risposte sopra.

Ho scoperto che i comandi più complessi devono essere incapsulati tra virgolette per funzionare:

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

1

puoi semplicemente scrivere il codice in .batun'estensione di formato, il codice del file batch:

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

usa questo codice c #:

Process.Start("file_name.bat")


se si desidera nascondere il cmd durante l'esecuzione, è possibile utilizzare un semplice codice di script Visual Basic in .vbsun'estensione di formato, il codice:CreateObject("Wscript.Shell").Run "filename.bat",0,True
XMMR12
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.