En ocasiones, necesitamos que nuestra aplicación ejecute un comando de consola (cmd.exe) para obtener datos de alguna aplicación de consola ó simplemente para poner en marcha un servicio. La manera sencilla y tosca res ejecutar el comando redirigiendo la salida a un archivo, después abrir el archivo y coger el resultado para procesarlo.
Este ejemplo presenta la forma elegante, creamos un proceso y redirigimos los Streams de entrada y salida hacia nuestro programa para poder enviar y recibir datos de forma asíncrona.
static void Main(string[] args)
{
// Creamos un nuevo proceso
Process p = new Process();
// Apuntamos al interprete de comandos
p.StartInfo.FileName = "cmd.exe";
// Indico los argumentos, ‘Q’ para suprmir el eco
// y ‘C’ para indicar el comando que ha de ejecutar
// y luego finalizar.
p.StartInfo.Arguments = "/Q /C sc query type= driver type= kernel";
// Indicamos que no cree una nueva ventana.
p.StartInfo.CreateNoWindow = true;
// Aunque a simple vista deberia ser ‘true’, para poder
// redirigir los streams tiene que ser ‘false’.
p.StartInfo.UseShellExecute = false;
// Habilitamos que se puedan lanzar el evento Exited.
p.EnableRaisingEvents = true;
//Redirigimos la salida
p.StartInfo.RedirectStandardOutput = true;
// Indicamos el encoding para la salida.
p.StartInfo.StandardOutputEncoding = Encoding.ASCII;
// Redirigimos la entrada.
p.StartInfo.RedirectStandardInput = true;
// Redirigimos los errores.
p.StartInfo.RedirectStandardError = true;
// Indicamos el encoding para la salida de erroes.
p.StartInfo.StandardErrorEncoding = Encoding.ASCII;
// Subscribimos el evento donde recibiremos las líneas de salida.
p.OutputDataReceived += new DataReceivedEventHandler(OutputDataReceived);
// Subscribimos el evento donde recibiremos las líneas de salida de errores.
p.ErrorDataReceived += new DataReceivedEventHandler(ErrorDataReceived);
// Subscribimos el evento donde se nos dirá que el proceso ha finalizado
p.Exited += new EventHandler(Exited);
// Iniciamos el proceso
p.Start();
// Iniciamos la lectura asíncrona del buffer de salida.
p.BeginOutputReadLine();
// Iniciamos la lectura asíncrona del buffer de errores.
p.BeginErrorReadLine();
p.WaitForExit();
Console.ReadKey();
}
static void Exited(object sender, EventArgs e)
{
Console.WriteLine("Fin del proceso");
}
static void ErrorDataReceived(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
Console.WriteLine("ERR : {0}", e.Data);
}
static void OutputDataReceived(object sender, DataReceivedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Data))
Console.WriteLine(e.Data);
}