Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   API de Windows (https://www.clubdelphi.com/foros/forumdisplay.php?f=7)
-   -   Enviarle un comando (string) a una aplicacion (consola) desde delphi (https://www.clubdelphi.com/foros/showthread.php?t=66497)

Rolando Glez 23-02-2010 15:57:54

Enviarle un comando (string) a una aplicacion (consola) desde delphi
 
Hola a todos pues tengo un problema resulta que quiero enviarle un comando a una aplicacion de consola desde delphi, necesito capturar tanto su salida ,asi como enviarle comandos desde la aplicacion delphi, el programa de consola es un "engine" de ajedrez, que puede tener varios mode (uci) que siginfica universal chess interface pues bien la idea es capturar todas las salida del programa hasta devuelva la cadena "bestmove", como ven ,no solo necesito capturar su salida que quizas se pueda lograr con pipes sino tambien enviarle comandos y que la aplicacion consola actue en dependencia del comando que se envie desde la aplicacion delphi digamos si envio el comando "go" el programa de consola debe de comenzar a enviar "info" sobre la salida hasta que programa devuelva "bestmove" en su salida standart (output), si envio "stop" debe de parar etc he visto varios ejemplo de pipes pero la mayoria es solo para obtener la salida de la aplicacion de consola y yo lo que necesito es tanto obtener esa salida digamos para ponerla en un memo asi como enviarle comandos a la aplicacion de consola es decir enviarle "go" cuando la aplicacion de consola esta esperando por un comando, no he hecho nunca ninguna aplicacion que utilice pipes pero creo que con esto es que se puede lograr, la duda es como le envio un comando a la aplicacion de consola donde su entrada es la standart(input) sin por supuesto tener que teclearla desde el keyboard, gracias por adelantado

droguerman 23-02-2010 20:49:45

1 Archivos Adjunto(s)
Necesitas Crear un Proceso y un par de Threads creadas con la función CreateThread que lo hagan, no es muy dificil, te envio una clase que uso para crear el proceso y un enlace http://support.microsoft.com/kb/190351 que indica como hacerlo, si necesitas más ayuda enviame otro post

Rolando Glez 29-12-2010 18:30:35

Logre mi proposito con ! pipes !
 
Gracias Droguerman por su colaboracion pues logre la conexion con la aplicacion de consolo a travez de Pipes (tuberias) estaba en el camino correcto pero parece que tenia puesta Una "tuberia al revez (handle) " pero cuando lo puse correctamente ,Bingo..... ahora mi programita trabaja perfectamente le puedo pasar comandos asi como tambien el se los devuelve a la aplicacion delphi ya logro que el engine (motor de ajedrez) juegue tanto con usuario asi como con el mismo ahora estoy pensando en perfeccionarlo y te permita que trabaje con dos engines a la vez lo que permitiria que jueguen dos engines previamente cargados etc en fin muchas gracias pues me ha dado cierta experiencia en esto de los pipes desde delphi para futuros programa que usen esta tecnica en Delphi . saludos y Feliz 2011 :D

Flecha 13-01-2011 13:22:08

Hola a todos.

Estoy buscando algo para poder capturar las salidas por vía standard de programas que son llamados desde Delphi utilizando WinExec() o cualquier otra cosa equivalente.
Un ejemplo simple de lo que busco es ejecutar WinExec('DIR',0) y que el resultado (listado del contenido del directorio actual), lo pueda mostrar dentro de un TMemo.
A poder ser me gustaría tener que prescindir de cosas como WinExec('DIR > resultado.txt', 0), porque obviamente lo necesito para cosas bastante más complejas que ejecutar un simple DIR.

He leido este hilo y me ha llamado la atención lo de la utilización de Pipes.
Quizá lo he entendido mal. Pero me ha parecido entender que con pipes se conseguiría lo que busco, y además también enviar comandos a aplicaciones.
¿Podría alguien explicarme en qué consiste lo de las Pipes y cómo poder hacerlo yo también?

La solución que aportó droguerman..., ¿está basada en Pipes?
La solución que encontró Rolando Glez..., ¿está basada en la droguerman..., o son dos soluciones distintas que no tienen nada que ver?

¿Se pueden establecer pipes a aplicaciones ubicadas en otros PC (acceso remoto)?

Muchas gracias.

Rolando Glez 17-02-2011 17:43:44

Funsiones Principales para abordar PIPES (redirecionamiento)
 
Aqui les mando las funsiones principales parea abordar esta tecnica de PIPES espero que le sea util




//Las variables

Código:

    type
    Tbuffer=array[1..4096] of char;
 
var

        pi: PROCESS_INFORMATION;
        sd: SECURITY_DESCRIPTOR;
        si: TSTARTUPINFO;
        sa: SECURITY_ATTRIBUTES;
  buffer: Tbuffer;

function IsWinNT: boolean;//Funsion auxiliar
var
  OSV: OSVERSIONINFO;
begin
  OSV.dwOSVersionInfoSize := sizeof(osv);
  GetVersionEx(OSV);
  result := OSV.dwPlatformId = VER_PLATFORM_WIN32_NT;
end;

// La siguiente funsion crea el redireccionamiento (PIPE) tuberia


procedure TFormMain.Createpipe(cmdline : string);
// se le debe pasar programa de consola a controlar

var ProcessInfo : TProcessInformation;
    startupInfo : TStartupInfo;
    namep,Programexe:Pchar;


begin
 if IsWinNT then
  begin
    InitializeSecurityDescriptor(@sd, SECURITY_DESCRIPTOR_REVISION);
    SetSecurityDescriptorDacl(@sd, true, nil, false);
    sa.lpSecurityDescriptor := @sd;
  end
  else
  sa.lpSecurityDescriptor := nil;
  sa.nLength := sizeof(SECURITY_ATTRIBUTES);
  sa.bInheritHandle := true;


 if CreatePipe(newstdin1, write_stdin1, @sa, 0) then
  begin
    if CreatePipe(read_stdout1, newstdout1, @sa, 0) then
    begin
      GetStartupInfo(si);
        with si do
      begin
        dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
        wShowWindow := SW_HIDE;
        hStdOutput := newstdout1;
        hStdError  := newstdout1;
        hStdInput  := newstdin1;
        //hStdInput :=GetStdHandle(STD_INPUT_HANDLE)
      end;
      Fillchar(Buffer, SizeOf(Buffer), 0);
      StrPCopy(buffer,cmdline);
      Fillchar(Buffer, SizeOf(Buffer), 0);
      GetEnvironmentVariable('COMSPEC', @Buffer, SizeOf(Buffer) - 1);
      Programexe:=pchar(cmdline);
      namep:=pchar(extractfilename(cmdline));
      CreateProcess(nil, PChar(cmdline),nil, nil, True,CREATE_NEW_CONSOLE, nil, nil,Si, Pi);
      end;
  end
 end;


//Este procedimiento lee sobre la tuberia creada

function TFormMain.ReadPipe(var  s:Tbuffer): Boolean;
var
dwAvail, dwRead : Cardinal;
PipeHandle : THandle;
lines:integer;

begin
Result := False;
line:='';
dwAvail := 6;
PipeHandle:=read_stdout1;
lines:=1;
repeat
            PeekNamedPipe(read_stdout1, @buffer, SizeOf(buffer) - 1, @bread, @avail, nil);// inspecciona si hay algo en la tuberia sin  extraer 
            if bread>0 then
            begin
            ReadFile(read_stdout1, buffer, bread, bread, nil);// lee pipe
            line:=buffer;//deposita en line contenido buffer
            memo1.Lines.Add(buffer);
            inc(lines);
            end;
            Application.ProcessMessages;
          //GetExitCodeProcess(pi.hProcess, exitcod);
until (bread=0);
if bread>0 then Result := True
              else result := false;
s:=buffer;
Application.ProcessMessages;
end;

// Este procedimiento escribe sobre la tuberia (envia comandos a programa de consola)

procedure TFormMain.WritePipe(s: string);
var Pstr : Tbuffer;
    len : cardinal;
    Wasok:boolean;

begin

StrPCopy(Pstr, s);
len := length(s);
Wasok:=Writefile(write_stdin1, Pstr, len, len, nil);  //se debe escribir sobre la entrada standart de proceso de consola
if not wasok then showmessage('error write in pipe')
     

end;

Bueno espero que le sea util aqui en este foro hay personas geniales
y todos nos ayudamos mutuamentes:D

morsa 04-10-2012 22:02:25

Delphi e interfaz UCI
 
Rolando,

podrías poner el código completo. He intentado manejar el stdinput y stdoutput con diferentes versiones de código y simplemente no puedo echar a andar ningún uci engine con mi programa. Gracias de antemano.

saludos
Manuel López

morsa 12-10-2012 19:09:04

Hallé en el sitio torry . net un componente threaded tpipe. Hace la comunicación simple y sin problemas. Eso resolvió mis dificultades, para quien le interese. Está en el sitio mencionado, en la sección system.

saludos

mosco 18-10-2012 00:33:38

Por favor MORSA ¿puedes explicarnos un poco como lo adaptaste? o ¿no tacaste el codigo?.

Gracias.

mosco 02-11-2012 20:56:38

Morsa no responde pero he estado estudiando el codigo de Torry.
Consigo que se abra la aplicacion con CreateProcess pero luego no puedo enviar ni recibir nada mas por las pipes creadas. ¿Alguien puede hechar una mano, por favor?.

mosco 03-11-2012 21:00:33

Resuelto. El codigo de Torry.net funciona. Lo he conseguido adaptar a mis necesidades. Ha llevado bastante tiempo y dedicación pero va muy bien.


La franja horaria es GMT +2. Ahora son las 03:36:04.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi