Como veo el standardoutput de la CMD en la própia CMD?

Iniciado por Eleкtro, 11 Enero 2013, 10:29 AM

0 Miembros y 1 Visitante están viendo este tema.

Eleкtro

Estoy intentando hacer pruebas,

Lo que quiero es poder abrir un comando en la CMD y que la consola no se cierre, por ejemplo:

Código (vbnet) [Seleccionar]
 My_Process_Info.FileName = "CMD.exe"
       My_Process_Info.Arguments = "/k pause"


Pero la CMD se cierra.

Así que he intentado ejecutar un FOR de Batch muy largo en la CMD para ver si así no se cierra...
Código (vbnet) [Seleccionar]
       My_Process_Info.FileName = "CMD.exe" ' Process filename
       My_Process_Info.Arguments = "/k For /L %a in (1,1,100000) do echo afijgifjigjfgjifjgi" ' Process arguments


y no, no se cierra (Porque el FOR tarda en finalizar, cuando acaba si que se cierra claro xD) pero ahora lo que ocurre además es que el output de la CMD no se muestra en la CMD!, es decir, el FOR no muestra nada.

EDITO: Vale, he descubierto que el output no se muestra en la CMD porque al habilitar la propiedad de redireccionar el Standard u Error output, no muestra el output en la CMD.


Así que quiero solucionar los dos problemas:

1. Que la CMD no se cierre cuando finaliza la orden, el comando.
2. Que el output se muestre en la CMD cuando habilito la propiedad RedirectStandardOutput = True  y/o RedirectStandardError = True




Este es el code, es un snippet que estoy intentando hacer:
Código (vbnet) [Seleccionar]
Dim My_Process As New Process()
       Dim My_Process_Info As New ProcessStartInfo()

       My_Process_Info.FileName = "CMD.exe" ' Process filename
       My_Process_Info.Arguments = "/k For /L %a in (1,1,100000) do echo afijgifjigjfgjifjgi" ' Process arguments
       My_Process_Info.UseShellExecute = False ' Don't use system shell to execute the process
       My_Process_Info.CreateNoWindow = False ' Show the CMD Window
       My_Process_Info.RedirectStandardOutput = True '  Redirect (1) Output
       My_Process_Info.RedirectStandardError = True ' Redirect non (1) Output
       My_Process.EnableRaisingEvents = True
       My_Process.StartInfo = My_Process_Info
       My_Process.Start() ' Run the process
       My_Process.WaitForExit() ' Wait X miliseconds to kill the process

       Dim Process_StandardOutput = My_Process.StandardOutput.ReadToEnd() ' Stores the Standard Output (If any)
       Dim Process_ErrorOutput = My_Process.StandardOutput.ReadToEnd() ' Stores the Error Output (If any)
       Dim Process_StartTime As String = My_Process.StartTime ' Stores the time when the process was launched
       Dim Process_EndTime As String = My_Process.ExitTime ' Stores the time when the process was finished
       Dim ERRORLEVEL = My_Process.ExitCode ' Stores the ExitCode of the process

       Dim result = Process_StartTime & vbNewLine & Process_EndTime & vbNewLine & ERRORLEVEL

       MsgBox(result)
       MsgBox(Process_StandardOutput)
       MsgBox(Process_ErrorOutput)








kub0x

Cita de: EleKtro H@cker en 11 Enero 2013, 10:29 AM
EDITO: Vale, he descubierto que el output no se muestra en la CMD porque al habilitar la propiedad de redireccionar el Standard u Error output, no muestra el output en la CMD.

Eso se debe a que tienes que inicializar la propiedad "UseShellExecute" a False, ya que para redireccionar los flujos de entrada/salida/error utilizarás la clase Process. UseShellExecute, como habrás visto crea una nueva instancia del CMD en la ruta donde se encuentre el ensamblado, con la que puedes interactuar como si de la Shell del sistema se tratase, solo que no puedes capturar los errores y las salidas.

Básicamente lo que hago es escribir en el Flujo de entrada del CMD, de esta forma consigo enviarle comandos en un Bucle que tiene como condición ejecutar los comandos hasta que el Comando sea nulo. En segundo plano capturo el evento OutPutDataRecieved asíncronicamente lo que me permite Leer y Escribir en la CMD a la vez ;)

Código (VB.NET) [Seleccionar]

Module Module1
Module Module1
    Sub Main()
        Dim p As New Process()
        With p.StartInfo
            .FileName = "cmd"
            .UseShellExecute = False
            .CreateNoWindow = False
            .WindowStyle = ProcessWindowStyle.Hidden
            .RedirectStandardOutput = True
            .RedirectStandardInput = True
            .RedirectStandardError = True
        End With
        AddHandler p.OutputDataReceived, AddressOf OutPutDataArrival
        p.Start()
        p.BeginOutputReadLine()
        Dim StdInput As IO.StreamWriter = p.StandardInput
        Dim Comando As String
        Do
            Comando = Console.ReadLine
            StdInput.WriteLine(Comando)
        Loop Until Comando Is String.Empty
        StdInput.Close()
    End Sub
    Private Sub OutPutDataArrival(ByVal Sender As Object, ByVal e As DataReceivedEventArgs)
        Console.WriteLine(e.Data)
    End Sub
End Module


Saludos!
Viejos siempre viejos,
Ellos tienen el poder,
Y la juventud,
¡En el ataúd! Criaturas Al poder.

Visita mi perfil en ResearchGate


Eleкtro

Demasiado bueno para ser cierto, leer, escribir, y sin cerrarse la CMD

Pero... ¿Hay forma de modificar el SUB OutPutDataArrival para hacerlo funcionar en un WinForm?

gracias