2009-09-24 17 views
432

¿Hay alguna manera de ejecutar comandos del símbolo del sistema desde una aplicación C#? Si es así, ¿cómo voy a hacer lo siguiente?Ejecutar comandos del indicador de comando

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

Esto básicamente incluye un archivo RAR dentro de la imagen JPG. Me preguntaba si había una manera de hacer esto automáticamente en C#. Gracias.

+6

duplicados de http://stackoverflow.com/questions/181719/how-to-start-a-process-from -c-winforms (hay una respuesta allí que hace lo que quieres). –

+0

http://stackoverflow.com/a/5367686/492 tiene una mejor respuesta –

Respuesta

679

esto es todo lo que tiene que hacer ejecutar comandos shell de C#

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

EDIT:

Esto es para ocultar la ventana de 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(); 
+11

¡Eso funciona genial! ¿Puedo preguntar para qué es "/ C"? – user

+124

/C Realiza el comando especificado por una cadena y luego termina –

+11

es solo para decirle al cmd que se ejecute y termine (no espere a que ningún usuario ingrese para cerrar la ventana) – RameshVel

8

Sí, lo hay (ver el enlace en el comentario de Matt Hamilton), pero sería más fácil y mejor usar las clases IO de .NET. Puede usar File.ReadAllBytes para leer los archivos y luego File.WriteAllBytes para escribir la versión "incrustada".

+10

Cargar archivos completos en la memoria solo para agregar uno a otro no es muy eficiente, especialmente si los archivos son lo suficientemente grandes. –

+5

Intenta mirar el espíritu de la respuesta. El punto es que .NET tiene clases y funciones IO más que suficientes para hacer esto sin tener que llamar al shell del sistema operativo. Las funciones particulares que mencioné pueden no ser las mejores, pero esas fueron simplemente las más simples. No tiene ningún sentido llamar al caparazón para hacer esto. –

10

Aunque técnicamente esto no responde directamente a la pregunta planteada, no responder a la pregunta de cómo hacer lo que el cartel original quería hacer: combinar archivos. En todo caso, esta es una publicación para ayudar a los novatos a comprender de lo que están hablando Instance Hunter y Konstantin.

Este es el método que uso para combinar archivos (en este caso, un jpg y un zip). Tenga en cuenta que creo un búfer que se llena con el contenido del archivo zip (en fragmentos pequeños en lugar de en una gran operación de lectura), y luego el búfer se escribe en la parte posterior del archivo jpg hasta que finaliza el archivo zip alcanzados:

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); 
      } 
     } 
    } 
} 
21
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); 
+0

¿Cuál es el signo '@' en C#? – Pacerier

+5

@Pacerier Le dice al compilador que debe escapar de todos los caracteres que normalmente deberían escaparse en la cadena, en este caso \. Entonces, sin \, su código se vería como 'proc1.FileName =" C: \\ Windows \\ System32 \\ cmd.exe ";' –

+0

@JamesKo, Ah lo encontró: http://stackoverflow.com/q/556133/632951. Google todavía es bastante pésimo en los símbolos. – Pacerier

68

Probamos solución @RameshVel pero no podía pasar argumentos en mi aplicación de consola. Si alguien experimenta el mismo problema aquí hay una solución:

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

Bueno, no le di ninguna oportunidad de pensar que en mi máquina existen algunas restricciones de administración o antivirus, pero ... ¡el código anterior funciona! gracias Ogglas –

+4

esta línea: cmd.StartInfo.CreateNoWindow = true; salvó mi día –

+3

Esta es la mejor respuesta que yo creo – zezba9000

5

Aquí hay una versión de código poco simple y menos. Se ocultará la ventana de la consola también-

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

Esto ya fue publicado anteriormente – cristi71000

3

con una referencia a Microsoft.VisualBasic

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

Ninguna de las respuestas anteriores ayudado por alguna razón, parece que barren errores debajo de la alfombra y hacer que la solución de problemas de uno comando difícil. Así que terminé yendo con algo como esto, tal vez va a ayudar a alguien más:

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

Si quisiera compilar esto en una aplicación de consola independiente, ¿qué otro código debería agregarse para que funcione? (Soy un novato en todo esto de programación, solo he hecho algunas secuencias de comandos). Estoy usando csc.exe por cierto. –

+0

@copyitright Un espacio de nombre y clase. Si acaba de crear un nuevo proyecto, se generarán para usted. – coinbird

2

Usted puede hacer esto utilizando CliWrap en una línea:

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

se puede lograr esto mediante el siguiente método (como se ha mencionado en otras respuestas):

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

Cuando traté de los métodos mencionados anteriormente he encontrado que mi comando personalizado no funcionaba utilizando la sintaxis de algunas de las respuestas anteriores.

me enteré de comandos más complejos necesitan ser encapsulada entre comillas para trabajar:

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