Procesos en .NET
agosto 14, 2008
Lanzando y monitorizando programas externos desde .NET
El namespace System.Diagnostics tiene una clase Process en el que usted puede lanzar programas externos. Usted pasará el nombre de un archivo ejecutable o un archivo con una extensión asociada con una aplicación ejecutable.
System.Diagnostics.Process.Start(“c:\…\MyTextFile.txt”)
Este código retorna un objeto Process:
Dim myProcess As Process = System.Diagnostics.Process.Start("c:\...\MyTextFile.txt")
MessageBox.Show(myProcess.ProcessName)
Un método sobrecargado Process.Start toma un parámetro ProcessStartInfo que deja a usted configurar los valores de inicialización tal como WindowStyle.
Dim psInfo As New System.Diagnostics.ProcessStartInfo ("c:\...\MyTextFile.txt")
psInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
Dim myProcess As Process = System.Diagnostics.Process.Start(psInfo)
O
Dim myProcess As System.Diagnostics.Process = new System.Diagnostics.Process()
myProcess.StartInfo.FileName = "c:\...\MyTextFile.txt"
myProcess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Normal
myProcess.Start
Usted puede también hacer todo a través del IDE arrastrando un componente Process dentro de su formulario desde el área de componentes de la barra de herramientas.
Iniciar un proceso y esperar hasta que este termine
Para esperar que un proceso lanzado finalice, llamé al método Process.WaitForExit. Su aplicación detendrá la ejecución hasta que el proceso lanzado termine. Sin embargo, Esto causará que su aplicación deje de responder a los eventos del sistema tal como el evento Paint.
'Comienza un nuevo proceso (Notepad).
'
Dim myProcess As Process = System.Diagnostics.Process.Start("MyTextFile.txt")
'
'Espera hasta que termine.
'
myProcess.WaitForExit()
MessageBox.Show("Notepad ended: " & myProcess.ExitTime & "." & _
System.Environment.NewLine & "Exit Code: " & myProcess.ExitCode)
'
'Cierra el proceso para liberar recursos
'
myProcess.Close()
Comenzar un proceso invisible
Usted puede iniciar un proceso y obtener su salida sin una ventana visible. El siguiente ejemplo muestra como cambiar a la carpeta de sistema, ejecute el comando DOS Dir “*.exe” y envié la salida al archivo Ouput.txt. El Shell de Windows XP reconoce “&&” como un comando separador, por lo tanto, usted puede poner múltiples comandos en una sola línea. El operador “>>” redirecciona la salida a un archivo.
Dim myProcess As Process = New Process()
Dim s As String
Dim outfile As String = Application.StartupPath & "\Output.txt"
'
'Obtener la ruta de Sistema.
'
Dim sysFolder As String = System.Environment.GetFolderPath(Environment.SpecialFolder.System)
'
'Crear la línea de comandos
'
myProcess.StartInfo.FileName = "cmd.exe"
myProcess.StartInfo.Arguments = "/C cd " & sysFolder & _
" && dir *.com >> " & Chr(34) & outfile & Chr(34) & " && exit"
'
'Comience el proceso en una ventana oculta
'
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
myProcess.StartInfo.CreateNoWindow = True
myProcess.Start()
'
'Termine el proceso si este no finalize en un minute
'
myProcess.WaitForExit(1000)
If Not myProcess.HasExited Then
myProcess.Kill()
End If
'
'Muestre los resultados
'
MessageBox.Show("The 'dir' command window was " & _
"closed at: " & myProcess.ExitTime & "." & System.Environment.NewLine & _
"Exit Code: " & myProcess.ExitCode)
myProcess.Close()
Determinar cuando un proceso termina
La clase proceso lanza un evento Exited cuando un proceso finaliza. Usted debe configurar la propiedad Process.EnableRaisingEvents y crear un manejador de evento.
myProcess.EnableRaisingEvents = True
'
'Añadir un manejador de eventos.
'
AddHandler myProcess.Exited, AddressOf Me.ProcessExited
'
myProcess.Start()
'
' Manejador de evento
'
Friend Sub ProcessExited(ByVal sender As Object, _
ByVal e As System.EventArgs)
Dim myProcess As Process = DirectCast(sender, Process)
MessageBox.Show("The process exited, raising " & _
"the Exited event at: " & myProcess.ExitTime & _
"." & System.Environment.NewLine & "Exit Code: " & myProcess.ExitCode)
myProcess.Close()
End Sub
Nota, Si el proceso lanzado no responde, también lo hará su aplicación
Controlando el proceso de Entrada y Salida
Usted puede necesitar enviar una entrada directamente a un proceso lanzado y enviar la salida directamente a su programa. Para programas que usan StdIn, StdOut y StdErr, tal como aplicaciones de consola, usted puede sobrescribir los valores por defecto y proveer un StreamWriter para escribir una entrada y StreamReaders para leer las salidas StdOut y StdErr.
.NET usa la función Win32 ShellExecute para lanzar procesos entonces cuando usted quiera reasignar Streams de entrada y salida, usted debe configurar la propiedad ProcessStartInfo.UseShellExecute a false antes de comenzar el proceso. También usted debe especificar la ruta completa del archivo o la ubicación del archivo que deberá estar en la cadena de ruta environmet o en uno de los lugares de búsqueda de Windows para archivos.
Dim myProcess As Process = New Process()
Dim s As String myProcess.StartInfo.FileName = "cmd.exe"
myProcess.StartInfo.UseShellExecute = False
myProcess.StartInfo.CreateNoWindow = True
myProcess.StartInfo.RedirectStandardInput = True
myProcess.StartInfo.RedirectStandardOutput = True
myProcess.StartInfo.RedirectStandardError = True
myProcess.Start()
Dim sIn As StreamWriter = myProcess.StandardInput
Dim sOut As StreamReader = myProcess.StandardOutput
Dim sErr As StreamReader = myProcess.StandardError
sIn.AutoFlush = True
sIn.Write("dir c:\windows\system32\*.com" & System.Environment.NewLine)
sIn.Write("exit" & System.Environment.NewLine)
s = sOut.ReadToEnd()
If Not myProcess.HasExited Then
myProcess.Kill()
End If
MessageBox.Show("The 'dir' command window was " & _
closed at: " & myProcess.ExitTime & "." & _
System.Environment.NewLine & "Exit Code: " & myProcess.ExitCode)
sIn.Close()
sOut.Close()
sErr.Close()
myProcess.Close()
MessageBox.Show(s)
Para programas que no usen StdDin, usted puede usar el método SendKeys para ingresar teclas.
Dim myProcess As Process = New Process()
myProcess.StartInfo.FileName = "notepad"
myProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal
myProcess.EnableRaisingEvents = True
AddHandler myProcess.Exited, AddressOf Me.SendKeysTestExited
myProcess.Start()
'
' Wait until the program is ready for input.
'
myProcess.WaitForInputIdle(1000)
If myProcess.Responding Then
System.Windows.Forms.SendKeys.SendWait( _
"This text was entered using SendKeys.")
Else
myProcess.Kill()
End If