Deteccion STDOUT

Pregunta Sin Miedo no te cortes cualquier cosa para empezar - Autoit se comienza facilmente.Para Ordenes o Comandos sueltos. Ver nota como preguntar.
Responder
Marcelo
Aprendiz de Mago
Mensajes: 34
Registrado: 29 Ene 2011, 18:13

Deteccion STDOUT

Mensaje por Marcelo »

Hola, ante todo, no sé si estará bien elegido el título del post pero no sabía cómo llamarlo.
Bueno, la pregunta es la siguiente: Tengo un programa de línea de comando al que deseo hacerle una interfaz (GUI), este va informando el proceso de trabajo mediante salida STDOUT.
¿Existe alguna manera, función, UDF, o como sea de ir leyendo estas salidas en tiempo real para poder ir informándolas tal cual aparecen en la GUI o necesariamente hay que esperar a que termine para poder obtenerlas?
Sé que se podría crear una salida a un archivo, pero estoy en la misma ya que el archivo no puede ser leido hasta que esté cerrado y el proceso puede tardar vaaaarios minutos y nunca se sabría si el programa sigue corriendo o se ha colgado...
Desde ya muchísimas gracias

Marcelo
Avatar de Usuario
Dany
Profesional del Autoit
Mensajes: 651
Registrado: 28 Mar 2012, 22:49

Re: Deteccion STDOUT

Mensaje por Dany »

  • ............................................Imagen
    ......................................Imagen
Marcelo
Aprendiz de Mago
Mensajes: 34
Registrado: 29 Ene 2011, 18:13

Re: Deteccion STDOUT

Mensaje por Marcelo »

Muchísimas gracias por la respuesta, perdón si hay algo que no entiendo. Pero para leer los valores mediante esa función no tengo que esperar que el proceso haya terminado?
De todas formas voy a ver si puedo darle vueltas al asunto e ir viendo...
Avatar de Usuario
Dany
Profesional del Autoit
Mensajes: 651
Registrado: 28 Mar 2012, 22:49

Re: Deteccion STDOUT

Mensaje por Dany »

puedes comentar que herramienta es para tener mas noción de lo que quieres hacer?
  • ............................................Imagen
    ......................................Imagen
Marcelo
Aprendiz de Mago
Mensajes: 34
Registrado: 29 Ene 2011, 18:13

Re: Deteccion STDOUT

Mensaje por Marcelo »

Perdón, por obviar eso. Son un par de cosas las que quiero hacer, pero entre ellas intentaría usar algún conversor de formatos de videos como el FFMPEG y me gustaría hacer algo parecido para el "clamscan.exe" del antivirus "clamav"
Sé que me dirán que existen ya cosas hechas para esto, pero quiero integrarlas a aplicaciones que ya tengo hechas y, por sobre todo, a título de "desafío personal", ya que sólo soy un programador hobbista. :smt002
Básicamente quiero ejecutar el "archivo.exe" con sus parámetros e ir informando de manera prolija en mi GUI cada una de las salidas que este vaya entregando, y así también poder informar el porcentaje de trabajo realizado...
Avatar de Usuario
Dany
Profesional del Autoit
Mensajes: 651
Registrado: 28 Mar 2012, 22:49

Re: Deteccion STDOUT

Mensaje por Dany »

mmm pues por ejemplo para el antivirus. supongamos que quieres hacer un scanner de antivirus con el commandline. la verdad no seria muy seguro ir leyendo la consola e ir parseando las cadenas. seria mejor escrbir en un txt. y luego parsear todo.


saludos tambien podrias analizar bien el commandline y hacer algo como quieres.



saludos
  • ............................................Imagen
    ......................................Imagen
Marcelo
Aprendiz de Mago
Mensajes: 34
Registrado: 29 Ene 2011, 18:13

Re: Deteccion STDOUT

Mensaje por Marcelo »

Ojo, que mi intención no es hacer el antivirus, sólo informar mediante un GUI.
No tengo acá el ejecutable porque estoy en una máquina linux, pero por lo que estuve viendo ayer puedo hacerte un ejemplo de memoria nomás.
La ejecución sería algo como "clamscan -r c:" y la salida algo como esto:

Cargando la base de datos /
Cargando la base de datos -
Cargando la base de datos \
Cargando la base de datos -
Cargando la base de datos /
Cargando la base de datos -
Cargando la base de datos \
Cargando la base de datos Listo
Analizando C:\Autoexec.bat: OK
Analizando C:\Archivo2.ext: OK
Analizando C:\Archivo3.ext: Nombre del virus encontrado FOUND
Analizando C:\Archivo4.ext: OK

y así hasta terminar.
Mi idea es poder poder asignar cada uno de esos "renglones" a un label dentro de la ventanita del GUI y, como ideal, por cada una de las que contengan FOUND hacer un parse y agregarlos a una lista con "nombre de archivo" e "infección".
Todo eso tengo en mente como hacerlo, lo único que no se si es posible es ir tomando cada una de las salidas para ir informándolas, ya que el proceso puede durar entre minutos y horas.

Agrego para no crear una nueva respuesta:

Bueno, estuve intentando algunas cosas y al parecer funciona, no pude aguantarme y lo estoy probando en linux con Wine así que la respuesta no es la óptima pero al menos parece que puedo ir tirando las salidas a la consola, será cosa de llegar a casa y probar algo más elaboradito en windows y ver qué pasa.
El código que estoy probando es el siguiente:

Código: Seleccionar todo

#include <Constants.au3>
Local $dos_output = "" 
Local $cmd = Run(@ScriptDir & "\clamscan.exe -r c:","",@SW_HIDE,$STDOUT_CHILD)
While Not @error 
    $dos_output &= StdoutRead($cmd) 
	ConsoleWrite($dos_output & @CRLF)
WEnd
MsgBox(0, "Terminado", $dos_output)
Llego a casa y lo pruebo mejor a ver cómo va y comento que fue lo que pasó... :smt002
Gracias Dany por tus respuestas!!!!
Marcelo
Aprendiz de Mago
Mensajes: 34
Registrado: 29 Ene 2011, 18:13

Re: Deteccion STDOUT

Mensaje por Marcelo »

Bueno, anoche después de renegar un rato y echarle la culpa a que el "peek" no funcionaba como debería hacerlo, puse una respuesta a este post preguntando si alguien tenía alguna idea de por qué no podía obtener las salidas una a una sino toda la acumulación de las mismas.
Ni bien termino de apretar el botón "enviar", veo en el código que el "&" de "$dos_output &=…" me saludaba. :smt002
Automáticamente dije NOOOOO, lo corregí, y puedo afirmar que funciona perfectamente para lo que necesito.
Cosas del "copiar y pegar" sin revisar en detalle.
Perdón, mala mía. ;)
Y gracias!!
Avatar de Usuario
juantxo
Hacker del Foro
Mensajes: 78
Registrado: 02 Abr 2008, 13:36

Re: Deteccion STDOUT

Mensaje por juantxo »

Me ha parecido un tema muy interesante, por lo que me he puesto ha hacer alguna prueba en base a tu Script, modificando el Comando que enviaba, pero no obtenia resultados en pantalla.

Si que mostraba informacion si añadia el parametro peek a la funcion StdoutRead ($cmd,True) pero concatenaba las lineas hasta que daba un error de memoria.

Creo que la culpa es del comando While que no termina nunca una vez que entra en el bucle, asi que he modificado el código como sigue:

Código: Seleccionar todo

#include <Constants.au3>
Local $dos_output = "", $txt_res = ""
Local $cmd = Run(@ComSpec & " /c " & "dir c:\ ", "", @SW_HIDE, $STDOUT_CHILD)

While ProcessExists($cmd)
	$dos_output = StdoutRead($cmd)
	If $dos_output <> "" Then
		ConsoleWrite($dos_output & @CRLF)
		$txt_res &= $dos_output
	EndIf

WEnd
MsgBox(0, "Terminado", $txt_res)
De esta forma, consigo el resultado del comando tanto en consola como en el MsgBox. :smt043 :smt036 :smt043

Pero algo no acaba de funcioar del todo porque si el comando no es interno de DOS como por ejemplo el CHKDSK

Código: Seleccionar todo

Local $cmd = Run(@ComSpec & " /c " & "CHKDSK c: ", "", @SW_HIDE, $STDOUT_CHILD)
o incluso

Código: Seleccionar todo

Local $cmd = Run("C:\Windows\System32\CHKDSK.exe", "", @SW_HIDE, $STDOUT_CHILD)

No obtengo resultado ninguno :smt018 :smt017 :smt018

¿alguna sugerencia de por que sucede esto?

:smt010 :smt010 :smt010
PDF
Hacker del Foro
Mensajes: 152
Registrado: 18 Ene 2013, 23:23

Re: Deteccion STDOUT

Mensaje por PDF »

Sin dudas es un tema interesante, por mi parte me puse a hacer mi propio ejemplo, utilizé el comando interno de windows CHKDSK y es el siguiente:

Código: Seleccionar todo

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>

$Form1 = GUICreate("Stdout Read", 464, 345, 223, 146)
$Label1 = GUICtrlCreateLabel("Verificando Unidad de disco:", 40, 16, 140, 17)
$Label2 = GUICtrlCreateEdit("", 40, 48, 380, 220)
GUICtrlSetData(-1, "")
$Progress1 = GUICtrlCreateProgress(40, 288, 382, 17)
$Input1 = GUICtrlCreateInput("H:", 200, 16, 121, 21)
$Button1 = GUICtrlCreateButton("Verificar", 336, 16, 75, 25)
$Label3 = GUICtrlCreateLabel("Listo", 40, 312, 388, 14)
GUISetState(@SW_SHOW)

While 1
	$nMsg = GUIGetMsg()
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case $Button1
			$Volume = GUICtrlRead($Input1)
			$Pro = Run(@ComSpec & " /c Chkdsk " & $Volume, "", @SW_HIDE, 2) ; Ejecuutamos la consola en modo oculto con el parametro $STDOUT_CHILD
			While ProcessExists($Pro) ; Verfica si existe el proceso
				$read = StdoutRead($Pro) ; Lee la salida STDOUT
				If StringInStr($read, "por ciento") Then
					GUICtrlSetData($Progress1, Number($read)) ; Utiliza el porcentaje que envia el Chkdsk para el progressbar
				Else
					GUICtrlSetData($Label2, $read, 1) ; Muestra el resultado en el edit
				EndIf
				GUICtrlSetData($Label3, $read)
			WEnd
			GUICtrlSetData($Progress1, 100) ; Generalmente queda en 99 por ciento completado, lo llenamos.
			GUICtrlSetData($Label3, "Listo")
	EndSwitch
WEnd
El resultado es mostrado en un edit y el progreso de la operación en un progressbar, sin esperar que se cierre el proceso de la consola, es decir, el resultado es mostrado en tiempo real..

Pero hay algo... al ejecutarse desde el SciTe, la consola se cierra inmediatamente por lo que se debe ejecutar directamente el archivo desde el menu contextual, a que se debera esto :smt017
Espero se entienda saludos!
Avatar de Usuario
Dany
Profesional del Autoit
Mensajes: 651
Registrado: 28 Mar 2012, 22:49

Re: Deteccion STDOUT

Mensaje por Dany »

@PDF el error creo que es por esta relación:

Código: Seleccionar todo

$dllcall=DllCall("msvcrt.dll","int:cdecl","printf","str","%s","str","Hola" & @CR)

Saludos :smt027
  • ............................................Imagen
    ......................................Imagen
PDF
Hacker del Foro
Mensajes: 152
Registrado: 18 Ene 2013, 23:23

Re: Deteccion STDOUT

Mensaje por PDF »

Mmm veo que el SciTE recoge también lo que envia la consola por medio de Sdout y tal vez se deba a esto.. Lo que decia es que, si ejecuto el script en el scite no hay resultados, pero si lo hago directamente funciona bien...
Marcelo
Aprendiz de Mago
Mensajes: 34
Registrado: 29 Ene 2011, 18:13

Re: Deteccion STDOUT

Mensaje por Marcelo »

Efectivamente Juantxo con StdoutRead($cmd,True) lee los valores de la salida pero no limpia el buffer, de esa forma siempre se obtiene la concatenación.
Para lo que buscamos, necesitamos ponerlo en "False" (valor por default)
Con respecto a la "NO información", a mi me pasaba, y era porque el bucle iba más rápido de lo que el programa generaba salidas, por decirlo de alguna manera.
Eso lo solucioné haciendo una comparación e informando únicamente si tenia qué

Código: Seleccionar todo

$out = StdoutRead($cmd,True)
If $out then
     guictrlsetdata($label,$out)
endif
Una vez capturados los datos hago las operaciones que quiero sobre el "string" e informo como quiero, nombre, porcentaje realizado, actualizo una lista cuando hay un objeto infectado, etc.
Para terminar, lo que hice fue lo mismo que en los ejemplos anteriores y es hacer el while verificando si el proceso seguía activo.
Hay casos en que determinados programas generan salidas en STDERR a la vez que STDOUT, para informar errores, eso también puede capturarse y no está de más.
Realmente muy entretenido!
Marcelo
Aprendiz de Mago
Mensajes: 34
Registrado: 29 Ene 2011, 18:13

Re: Deteccion STDOUT

Mensaje por Marcelo »

Dany escribió:@PDF el error creo que es por esta relación:

Código: Seleccionar todo

$dllcall=DllCall("msvcrt.dll","int:cdecl","printf","str","%s","str","Hola" & @CR)

Saludos :smt027
Dany, perdón por la ignorancia, pero ¿qué es lo que haría esa llamada?
Responder