Führen Sie Eingabeaufforderungsbefehle aus

605

Gibt es eine Möglichkeit, Eingabeaufforderungsbefehle in einer C # -Anwendung auszuführen? Wenn ja, wie würde ich Folgendes tun:

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

Dadurch wird im Grunde eine RAR-Datei in das JPG-Bild eingebettet. Ich habe mich nur gefragt, ob es eine Möglichkeit gibt, dies in C # automatisch zu tun.

Benutzer
quelle
6
Duplikat von stackoverflow.com/questions/181719/… (dort gibt es eine Antwort, die macht, was Sie wollen).
Matt Hamilton
stackoverflow.com/a/5367686/492 hat eine bessere Antwort
CAD-Typ

Antworten:

918

Dies ist alles, was Sie tun müssen, um Shell-Befehle von C # aus auszuführen

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

BEARBEITEN:

Dies dient zum Ausblenden des Cmd-Fensters.

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

BEARBEITEN: 2

Wichtig ist, dass das Argument mit beginnt, /Csonst funktioniert es nicht. Wie Scott Ferguson sagte: "Führt den durch die Zeichenfolge angegebenen Befehl aus und wird dann beendet."

RameshVel
quelle
166
/ C Führt den durch string angegebenen Befehl aus und wird dann beendet
Scott Ferguson
16
Es ist nur, um den Cmd anzuweisen, ausgeführt und beendet zu werden (warten Sie nicht, bis Benutzereingaben das Fenster schließen)
RameshVel
3
Vielen Dank, noch eine Frage. Gibt es eine Möglichkeit, die Eingabeaufforderung währenddessen auszublenden?
Benutzer
9
Ich verstehe nicht, wie ich der einzige bin, der das für eine schreckliche Idee hält. Ja, das wird funktionieren, aber es ist völlig falsch. Das Laichen von CMD-Prozessen für einfache E / A-Operationen ist falsch, selbst wenn es funktioniert. Lesen Sie die Dokumentation zum System.IO-Namespace durch. Es gibt mehr als genug Funktionen, um das zu tun, was Sie tun müssen, ohne unnötige Prozesse hervorzurufen.
Instance Hunter
56
Zu Ihrer Information: Verwenden Sie process.WaitForExit (), um auf den Abschluss des Prozesses zu warten, bevor Sie fortfahren, und process.ExitCode, um den Exit-Code des Prozesses abzurufen.
Shindigo
122

Versuchte @ RameshVel-Lösung, aber ich konnte keine Argumente in meiner Konsolenanwendung übergeben. Wenn jemand das gleiche Problem hat, ist hier eine Lösung:

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());
Ogglas
quelle
2
Nun, ich gab keine Chance zu denken, dass es auf meinem Computer einige Administrator- oder Antiviren-Einschränkungen gibt, aber .. der obige Code funktioniert! danke Ogglas
Pete Kozak
6
diese Zeile: cmd.StartInfo.CreateNoWindow = true; hat meinen Tag gerettet.
Ganesh Kamath - "Code Frenzy"
Gibt es eine Möglichkeit, mehrere Befehle in einem einzigen auszuführencmd.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);
HackerMan
quelle
2
Was ist das @Zeichen in C #?
Pacerier
6
@Pacerier Weist den Compiler an, alle Zeichen zu maskieren, die normalerweise in der Zeichenfolge maskiert werden müssten, in diesem Fall \. Ohne das \ würde Ihr Code also so aussehenproc1.FileName = "C:\\Windows\\System32\\cmd.exe";
James Ko
1
Man sollte beachten, proc1.Verb = "runas";dass dieser Prozess mit erhöhten Berechtigungen ausgeführt wird ... Dies ist nicht immer beabsichtigt.
Dinei
1
Wie kann ich dafür sorgen, dass dieses Cmd-Fenster nach Abschluss nicht geschlossen wird?
Hrvoje T
1
Ich habe festgestellt, dass der Aufruf von 'cd path', verbunden mit '&&' mit anderen Befehlen in der Zeile, immer zuletzt ausgeführt wird, selbst wenn er zuerst ausgeführt wurde. Ihr: 'proc1.WorkingDirectory = @ "C: \ Windows \ System32";' war sehr hilfreich! Vielen Dank!
Nozim Turakulov
11

Keine der oben genannten Antworten hat aus irgendeinem Grund geholfen. Es scheint, als würden sie Fehler unter den Teppich kehren und die Fehlerbehebung beim Befehl erschweren. Also habe ich so etwas gemacht, vielleicht hilft es jemand anderem:

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();
Matt Bonness
quelle
Wenn ich dies in eine eigenständige Konsolenanwendung kompilieren möchte, welcher andere Code müsste hinzugefügt werden, damit es funktioniert? (Ich bin ein Neuling in all dem Programmieren, habe nur ein paar Skripte geschrieben). Ich benutze übrigens csc.exe.
script'n'code
@copyitright Ein Namespace und eine Klasse. Wenn Sie nur ein neues Projekt erstellen, werden diese für Sie generiert.
Coinbird
Ah. keine Ursache. Wenn Sie die cmd.exeApp verwenden, können Sie Befehle als Argumente übergeben.
Zach Smith
Für die Nachwelt: Ich wollte, dass der Prozess ausgeführt wird echo Hello World!und die Befehlsausgabe im angezeigten cmd-Fenster angezeigt wird. Also habe ich versucht: Filename = @"echo", Arguments = "Hello World!", UseShellExecute = false, RedirectStandardOuput = false, CreateNoWindow = false. Dadurch konnte im cmd-Fenster der übergeordneten Anwendung "Hello World!" (Dies ist sinnvoll, da stdout nicht zum untergeordneten Prozess umgeleitet wurde.)
Minh Tran
10

Obwohl dies technisch gesehen die gestellte Frage nicht direkt beantwortet, beantwortet es die Frage, wie das zu tun ist, was das Originalplakat tun wollte: Dateien kombinieren. Wenn überhaupt, ist dies ein Beitrag, der Neulingen hilft zu verstehen, worüber Instance Hunter und Konstantin sprechen.

Dies ist die Methode, mit der ich Dateien kombiniere (in diesem Fall ein JPG und ein Zip). Beachten Sie, dass ich einen Puffer erstelle, der mit dem Inhalt der Zip-Datei gefüllt wird (in kleinen Blöcken anstatt in einem großen Lesevorgang), und der Puffer dann bis zum Ende der Zip-Datei auf die Rückseite der JPG-Datei geschrieben wird erreicht:

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);
            }
        }
    }
}
CarllDev
quelle
9

Wenn Sie das Cmd-Fenster offen halten oder in winform / wpf verwenden möchten, verwenden Sie es wie folgt

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

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

/ K.

Hält das cmd-Fenster offen

Einzigartiges Design
quelle
Nett. Diese Dokumentation für den cmdBefehl und seine Parameter wurde gefunden.
Pius
8

Ja, das gibt es (siehe Link in Matt Hamiltons Kommentar), aber es wäre einfacher und besser, die E / A-Klassen von .NET zu verwenden. Sie können File.ReadAllBytes verwenden, um die Dateien zu lesen, und dann File.WriteAllBytes, um die "eingebettete" Version zu schreiben.

Instanzjäger
quelle
11
Das Laden ganzer Dateien in den Speicher, nur um sie aneinander anzuhängen, ist nicht sehr effizient, insbesondere wenn die Dateien groß genug sind.
Konstantin Spirin
7
Versuchen Sie, den Geist der Antwort zu betrachten. Der Punkt ist, dass .NET über mehr als genug E / A-Klassen und -Funktionen verfügt, um dies zu tun, ohne die Betriebssystem-Shell aufrufen zu müssen. Die speziellen Funktionen, die ich erwähnt habe, sind vielleicht nicht die besten, aber diese waren nur die einfachsten. Es macht überhaupt keinen Sinn, die Shell dazu aufzurufen.
Instance Hunter
7

Sie können dies mit CliWrap in einer Zeile tun :

var stdout = new Cli("cmd")
         .Execute("copy /b Image1.jpg + Archive.rar Image2.jpg")
         .StandardOutput;
Tyrrrz
quelle
Ich habe dies positiv bewertet ... aber das Repo scheint jetzt zu fehlen:Unable to find package 'CliWrap' at source
Zach Smith
1
@ZachSmith nicht sicher, was du meinst, nuget.org/packages/CliWrap scheint gut zu funktionieren. Der ursprüngliche Link auch.
Tyrrrz
Ah.sorry .. aus irgendeinem Grund konnte ich dieses Paket nicht installieren, als ich über VPN keine Verbindung zu meinem Nuget Repo herstellen konnte. Nuget ist mir immer noch ein Rätsel. muss es falsch eingestellt haben
Zach Smith
6

mit einem Verweis auf Microsoft.VisualBasic

Interaction.Shell("copy /b Image1.jpg + Archive.rar Image2.jpg", AppWinStyle.Hide);
Slai
quelle
5

Hier ist wenig einfache und weniger Code-Version. Das Konsolenfenster wird ebenfalls ausgeblendet.

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();
Kamalpreet
quelle
5

Wenn Sie den Befehl im asynchronen Modus ausführen und die Ergebnisse drucken möchten. Sie können Sie diese Klasse:

    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
        }
    }

}
Elad
quelle
2

Sie können dies mit der folgenden Methode erreichen (wie in anderen Antworten erwähnt):

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

Als ich die oben aufgeführten Methoden ausprobierte, stellte ich fest, dass mein benutzerdefinierter Befehl mit der Syntax einiger der obigen Antworten nicht funktionierte.

Ich fand heraus, dass komplexere Befehle in Anführungszeichen gesetzt werden müssen, um zu funktionieren:

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

Sie können einfach den Code in einer Formaterweiterung schreiben .bat, den Code der Batch-Datei:

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

Verwenden Sie diesen C # -Code:

Process.Start("file_name.bat")

XMMR12
quelle
Wenn Sie das Cmd während der Ausführung ausblenden möchten, können Sie einen einfachen visuellen .vbsCreateObject("Wscript.Shell").Run "filename.bat",0,True
Basisskriptcode