¿Cómo ejecuto un programa de línea de comandos desde C# y obtengo los resultados STD OUT? Específicamente, quiero ejecutar DIFF en dos archivos que están seleccionados mediante programación y escribir los resultados en un cuadro de texto. Sí, podría resolver esto por mí mismo, pero seguramente alguien ha hecho algo parecido y yo soy un vago ...Cómo: Ejecutar línea de comandos en C#, obtener resultados STD OUT
Respuesta
// Start the child process.
Process p = new Process();
// Redirect the output stream of the child process.
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "YOURBATCHFILE.bat";
p.Start();
// Do not wait for the child process to exit before
// reading to the end of its redirected stream.
// p.WaitForExit();
// Read the output stream first and then wait.
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
El código es de MSDN.
Es habitual agregar una atribución cuando corta y pega código para otro lugar. Esto fue tomado de http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx –
¿Hay alguna manera de hacerlo sin un archivo por lotes? La cosa es que necesito enviar algunos parámetros al comando. Estoy usando el xsd.exe
Puede agregar argumentos a su llamada a través de la cadena '{YourProcessObject} .StartInfo.Arguments'. – patridge
esto puede no ser la mejor/manera más fácil, pero puede ser una opción:
Cuando ejecutas desde tu código, agrega "> salida.txt" y luego lee en el archivo output.txt.
Necesitará usar ProcessStartInfo
con RedirectStandardOutput
habilitado - entonces puede leer el flujo de salida. Es posible que le resulte más fácil utilizar ">" para redirigir la salida a un archivo (a través del sistema operativo), y luego simplemente lea el archivo.
[editar: al igual que lo hizo Ray: 1]
Eso obliga a escribir un archivo en algún lugar para el que necesita permiso, necesita encontrar una ubicación y un nombre y no debe olvidarse de eliminar cuando haya terminado con él. Más fácil de usar 'RedirectStandardOutput' en realidad. – peSHIr
Puede iniciar cualquier programa de línea de comandos usando la clase de proceso, y establezca la propiedad StandardOutput de la instancia de proceso con un lector corriente se crea (ya sea basada en una cadena o una ubicación de memoria). Después de que el proceso se complete, puedes hacer lo que necesites en esa transmisión.
System.Diagnostics.ProcessStartInfo psi =
new System.Diagnostics.ProcessStartInfo(@"program_to_call.exe");
psi.RedirectStandardOutput = true;
psi.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
psi.UseShellExecute = false;
System.Diagnostics.Process proc System.Diagnostics.Process.Start(psi);;
System.IO.StreamReader myOutput = proc.StandardOutput;
proc.WaitForExit(2000);
if (proc.HasExited)
{
string output = myOutput.ReadToEnd();
}
Aquí hay una muestra rápida:
//Create process
System.Diagnostics.Process pProcess = new System.Diagnostics.Process();
//strCommand is path and file name of command to run
pProcess.StartInfo.FileName = strCommand;
//strCommandParameters are parameters to pass to program
pProcess.StartInfo.Arguments = strCommandParameters;
pProcess.StartInfo.UseShellExecute = false;
//Set output of program to be written to process output stream
pProcess.StartInfo.RedirectStandardOutput = true;
//Optional
pProcess.StartInfo.WorkingDirectory = strWorkingDirectory;
//Start the process
pProcess.Start();
//Get program output
string strOutput = pProcess.StandardOutput.ReadToEnd();
//Wait for process to finish
pProcess.WaitForExit();
+1 ¡agradable y fácil! Gracias – Evildonald
hay una clase ProcessHelper en PublicDomain código fuente abierto que pueden interesarle.
cualquier código de muestra completo? – Kiquenet
Hay otro parámetro que encontraron útiles, que utilizo para eliminar la ventana de proceso
pProcess.StartInfo.CreateNoWindow = true;
esto ayuda a ocultar la ventana de la consola de usuario completamente negro, si eso es lo que desea.
Me salvó un montón de dolor de cabeza. Gracias. –
Al llamar a "sc" también tuve que configurar StartInfo.WindowStyle = ProcessWindowStyle.Hidden. – Pedro
// usage
const string ToolFileName = "example.exe";
string output = RunExternalExe(ToolFileName);
public string RunExternalExe(string filename, string arguments = null)
{
var process = new Process();
process.StartInfo.FileName = filename;
if (!string.IsNullOrEmpty(arguments))
{
process.StartInfo.Arguments = arguments;
}
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
var stdOutput = new StringBuilder();
process.OutputDataReceived += (sender, args) => stdOutput.AppendLine(args.Data); // Use AppendLine rather than Append since args.Data is one line of output, not including the newline character.
string stdError = null;
try
{
process.Start();
process.BeginOutputReadLine();
stdError = process.StandardError.ReadToEnd();
process.WaitForExit();
}
catch (Exception e)
{
throw new Exception("OS error while executing " + Format(filename, arguments)+ ": " + e.Message, e);
}
if (process.ExitCode == 0)
{
return stdOutput.ToString();
}
else
{
var message = new StringBuilder();
if (!string.IsNullOrEmpty(stdError))
{
message.AppendLine(stdError);
}
if (stdOutput.Length != 0)
{
message.AppendLine("Std output:");
message.AppendLine(stdOutput.ToString());
}
throw new Exception(Format(filename, arguments) + " finished with exit code = " + process.ExitCode + ": " + message);
}
}
private string Format(string filename, string arguments)
{
return "'" + filename +
((string.IsNullOrEmpty(arguments)) ? string.Empty : " " + arguments) +
"'";
}
Un ejemplo muy completo, Gracias – ShahidAzim
Puede que desee cambiar el manejador OutputDataReceived a stdOut.AppendLine() –
En mi opinión, esta es una solución mucho más completa que la aceptada. Lo estoy usando ahora, y no he usado el aceptado, pero realmente parece que falta. – ProfK
Esto podría ser útil para alguien si intenta consultar la memoria caché ARP local en una PC/Servidor.
List<string[]> results = new List<string[]>();
using (Process p = new Process())
{
p.StartInfo.CreateNoWindow = true;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.UseShellExecute = false;
p.StartInfo.Arguments = "/c arp -a";
p.StartInfo.FileName = @"C:\Windows\System32\cmd.exe";
p.Start();
string line;
while ((line = p.StandardOutput.ReadLine()) != null)
{
if (line != "" && !line.Contains("Interface") && !line.Contains("Physical Address"))
{
var lineArr = line.Trim().Split(' ').Select(n => n).Where(n => !string.IsNullOrEmpty(n)).ToArray();
var arrResult = new string[]
{
lineArr[0],
lineArr[1],
lineArr[2]
};
results.Add(arrResult);
}
}
p.WaitForExit();
}
Si no te importa la introducción de una dependencia, CliWrap puede simplificar esto para usted:
var cli = new Cli("target.exe");
var output = await cli.ExecuteAsync("arguments", "stdin");
var stdout = output.StandardOutput;
La respuesta aceptada en esta página tiene una debilidad que es problemático en situaciones raras. Hay dos manejadores de archivos a los que escriben los programas por convención, stdout y stderr. Si acaba de leer un identificador de archivo único como la respuesta de Ray, y el programa que está iniciando escribe suficiente salida en stderr, llenará el búfer stderr de salida y bloqueará. Entonces tus dos procesos están estancados. El tamaño del buffer puede ser 4K. Esto es extremadamente raro en programas de corta duración, pero si tiene un programa de ejecución prolongada que genera salidas repetidas a stderr, eventualmente ocurrirá. Esto es complicado de depurar y rastrear.
Hay un par de buenas maneras de lidiar con esto.
Una forma es ejecutar cmd.exe en lugar de su programa y utilizar el argumento/c para cmd.exe para invocar el programa junto con el argumento "2> & 1" a cmd.exe para contarlo fusionar stdout y stderr.
var p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = "/c mycmd.exe 2>&1";
Otra forma es utilizar un modelo de programación que se lee tanto maneja al mismo tiempo.
var p = new Process(); p.StartInfo.FileName = "cmd.exe"; p.StartInfo.Arguments = @"/c dir \windows"; p.StartInfo.CreateNoWindow = true; p.StartInfo.RedirectStandardError = true; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.RedirectStandardInput = false; p.OutputDataReceived += (a, b) => Console.WriteLine(b.Data); p.ErrorDataReceived += (a, b) => Console.WriteLine(b.Data); p.Start(); p.BeginErrorReadLine(); p.BeginOutputReadLine(); p.WaitForExit();
Sólo por diversión, aquí está mi solución completa para conseguir la salida PYTHON - bajo un clic de botón - con el informe de errores. Sólo tiene que añadir un botón llamado "butPython" y una etiqueta llamada "llHello" ...
private void butPython(object sender, EventArgs e)
{
llHello.Text = "Calling Python...";
this.Refresh();
Tuple<String,String> python = GoPython(@"C:\Users\BLAH\Desktop\Code\Python\BLAH.py");
llHello.Text = python.Item1; // Show result.
if (python.Item2.Length > 0) MessageBox.Show("Sorry, there was an error:" + Environment.NewLine + python.Item2);
}
public Tuple<String,String> GoPython(string pythonFile, string moreArgs = "")
{
ProcessStartInfo PSI = new ProcessStartInfo();
PSI.FileName = "py.exe";
PSI.Arguments = string.Format("\"{0}\" {1}", pythonFile, moreArgs);
PSI.CreateNoWindow = true;
PSI.UseShellExecute = false;
PSI.RedirectStandardError = true;
PSI.RedirectStandardOutput = true;
using (Process process = Process.Start(PSI))
using (StreamReader reader = process.StandardOutput)
{
string stderr = process.StandardError.ReadToEnd(); // Error(s)!!
string result = reader.ReadToEnd(); // What we want.
return new Tuple<String,String> (result,stderr);
}
}
- 1. Ejecutar línea de comandos en WiX Script?
- 2. ejecutar múltiples comandos en una línea de comandos
- 3. ¿Cómo obtener std :: cadena de argumentos de línea de comandos en la aplicación win32?
- 4. Ejecutar Java desde la línea de comandos
- 5. ¿Cómo ejecutar el programa Java y obtener resultados en PHP?
- 6. Cómo ejecutar ffmpeg desde la línea de comandos en android
- 7. ¿Cómo ejecutar Google Codepro Analytix desde la línea de comandos?
- 8. Ejecutar comandos de python pasados como cadenas en la línea de comandos usando python -c
- 9. Cómo ejecutar frasco con argumentos de línea de comandos
- 10. Cómo ejecutar una aplicación de consola con parámetros de línea de comandos en Visual C++ 6.0?
- 11. C++: cómo obtener los resultados de fprintf como un std :: string sin sprintf
- 12. Ejecutar el paquete osgi desde la línea de comandos
- 13. ¿Cómo puedo ejecutar comandos externos en C++/Linux?
- 14. Ejecutar un comando de línea de comandos desde CruiseControl.NET
- 15. Línea de comandos TFS de creación de scripts para Obtener la última versión, Check Out y Check in, mediante programación
- 16. depuración C# en la línea de comandos
- 17. Ejecutar aplicación Silex en la línea de comandos
- 18. Error al ejecutar comandos svn en la línea de cmd
- 19. Ejecutar proyecto de Eclipse desde la línea de comandos
- 20. Cómo analizar la salida de línea de comando de C#?
- 21. ¿Cómo ejecutar TODAS las pruebas en mi solución usando la línea de comandos MSTest.exe?
- 22. Cómo ejecutar un script de shell en segundo plano y no obtener resultados
- 23. Obtener resultados de los comandos de busybox dentro de la aplicación de Android
- 24. Cómo ejecutar comandos cmd a través de Java
- 25. Ejecutar comandos sqlite3 "punto" de Python o registrar intercalación en la utilidad de línea de comandos
- 26. Ejecutar línea de comandos y devolver la salida del comando
- 27. Cómo depurar un programa de línea de comandos C#
- 28. ¿Cómo ejecutar comandos USSD en android?
- 29. ¿Cómo cambio la salida de la consola de registro java de std err a std out?
- 30. Ejecutar JUnit Test suite desde la línea de comandos
Ver también http://stackoverflow.com/a/5367686/492 - que muestra los eventos para la salida y los errores. –