Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > API de Windows
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 16-01-2011
Avatar de kurono
[kurono] kurono is offline
Miembro Premium
 
Registrado: jul 2007
Ubicación: Republica Dominicana
Posts: 1.126
Poder: 18
kurono Va por buen camino
este te permite ejecutar comando de Ms-dos y ver sus resultados quisas seas lo que busca

Código Delphi [-]
function IsWinNT: boolean;
var
  OSV: OSVERSIONINFO;
begin
  OSV.dwOSVersionInfoSize := sizeof(osv);
  GetVersionEx(OSV);
  result := OSV.dwPlatformId = VER_PLATFORM_WIN32_NT;
end;

function CmdExec(Cmd: string): string;
var
  Buffer: array[0..4096] of Char;
  si: STARTUPINFO;
  sa: SECURITY_ATTRIBUTES;
  sd: SECURITY_DESCRIPTOR;
  pi: PROCESS_INFORMATION;
  newstdin, newstdout, read_stdout, write_stdin: THandle;
  exitcod, bread, avail: Cardinal;
begin
  Result:= '';
  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(newstdin, write_stdin, @sa, 0) then
  begin
    if CreatePipe(read_stdout, newstdout, @sa, 0) then
    begin
      GetStartupInfo(si);
      with si do
      begin
        dwFlags := STARTF_USESTDHANDLES or STARTF_USESHOWWINDOW;
        wShowWindow := SW_HIDE;
        hStdOutput := newstdout;
        hStdError := newstdout;
        hStdInput := newstdin;
      end;
      Fillchar(Buffer, SizeOf(Buffer), 0);
      GetEnvironmentVariable('COMSPEC', @Buffer, SizeOf(Buffer) - 1);
      StrCat(@Buffer,PChar(' /c ' + Cmd));
      if CreateProcess(nil, @Buffer, nil, nil, TRUE, CREATE_NEW_CONSOLE, nil, nil, si, pi) then
      begin
        repeat
          PeekNamedPipe(read_stdout, @Buffer, SizeOf(Buffer) - 1, @bread, @avail, nil);
          if bread > 0 then
          begin
            Fillchar(Buffer, SizeOf(Buffer), 0);
            ReadFile(read_stdout, Buffer, bread, bread, nil);
            Result:= Result + String(PChar(@Buffer));
          end;
          Application.ProcessMessages;
          GetExitCodeProcess(pi.hProcess, exitcod);
        until (exitcod <> STILL_ACTIVE) and (bread = 0);
      end;
      CloseHandle(read_stdout);
      CloseHandle(newstdout);
    end;
    CloseHandle(newstdin);
    CloseHandle(write_stdin);
  end;
end;

ejemplo de uso

begin

ShowMessage(CmdExec('dir c:\'));
ShowMessage(CmdExec('netstat -a -n'));

end;
end.
Responder Con Cita
  #2  
Antiguo 17-01-2011
Flecha Flecha is offline
Miembro
 
Registrado: nov 2006
Posts: 59
Poder: 18
Flecha Va por buen camino
Muchas gracias por responder, kurono. Pero por desgracia no me vale.

También he provado ese código que me ofreces. Pero no deja de ser una variante del truco de Trucomanía. Hay órdenes cuya respuesta no es capaz de capturar.

¿Alguien conoce otra alternativa?

Muchas Gracias.
Responder Con Cita
  #3  
Antiguo 25-01-2011
Avatar de newtron
[newtron] newtron is offline
Membrillo Premium
 
Registrado: abr 2007
Ubicación: Motril, Granada
Posts: 3.474
Poder: 21
newtron Va camino a la fama
Hola.

Igual digo una tontería pero los comandos de msdos si los acabas con el signo > seguido de un nombre crea un archivo con la salida del comando. Unicamente tendrías que ejecutar el comando msdos con el signo y el nombre del fichero y después leer el fichero que es un fichero de txt normal.

Saludos
Responder Con Cita
  #4  
Antiguo 25-01-2011
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is online now
Moderador
 
Registrado: sep 2004
Ubicación: En algún lugar.
Posts: 32.057
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por newtron Ver Mensaje
Hola.

Igual digo una tontería pero los comandos de msdos si los acabas con el signo > seguido de un nombre crea un archivo con la salida del comando. Unicamente tendrías que ejecutar el comando msdos con el signo y el nombre del fichero y después leer el fichero que es un fichero de txt normal.

Saludos
Exacto, y si en lugar de '>' pones '>>' lo que hace es añadirlo al final del fichero indicado.
Responder Con Cita
  #5  
Antiguo 26-01-2011
mcs mcs is offline
Miembro
 
Registrado: may 2007
Ubicación: Girona
Posts: 229
Poder: 18
mcs Va por buen camino
Cita:
Empezado por Casimiro Notevi Ver Mensaje
Exacto, y si en lugar de '>' pones '>>' lo que hace es añadirlo al final del fichero indicado.
siempre y cuando usen las funciones del DOS para escribir en pantalla, cosa que pocas aplicaciones hacían debido a que era muy lento... (lo fácil y rápido era escribir directamente a la memoria de la VGA... dirección $B8000000, si no recuerdo mal! )
Responder Con Cita
  #6  
Antiguo 26-01-2011
Avatar de newtron
[newtron] newtron is offline
Membrillo Premium
 
Registrado: abr 2007
Ubicación: Motril, Granada
Posts: 3.474
Poder: 21
newtron Va camino a la fama
Cita:
Empezado por mcs Ver Mensaje
siempre y cuando usen las funciones del DOS para escribir en pantalla, cosa que pocas aplicaciones hacían debido a que era muy lento... (lo fácil y rápido era escribir directamente a la memoria de la VGA... dirección $B8000000, si no recuerdo mal! )
....juer... 10 años programando en msdos y otros 10 en guindoun y ahora me entero de eso de escribir en la memoria de la vga.... dirección qué dices? jajajajajaja
Responder Con Cita
  #7  
Antiguo 26-01-2011
Flecha Flecha is offline
Miembro
 
Registrado: nov 2006
Posts: 59
Poder: 18
Flecha Va por buen camino
Espero no tener que vigilar las escrituras directas en VGA, porque para lo que necesito capturar la salida..., sería un auténtico engorro tener que andarme con esas cosas...


Ya sabía lo del > y el >> . Es lo más básico de lo más mínima programación elemental . Pero preferiría no tener que recurrir a ese truco.


De todos modos, muchas gracias a todos.
La captura de la salida a MS-DOS que necesito hacer, es sólo una pequeña parte de un problema mayor que debo resolver. Si consigo perfeccionar el resto de los puntos de mi problema, quizá no necesite ser "tan exigente" con la captura. Y en este caso, la solución presente en TrucoManía, y la presentada por kurono, cualquiera de las dos podría valerme.


No obstante. Debo reseñar una cosa al respecto de sendas soluciones. Ambas tienen un bucle, dentro del cual se va capturando la salida a MS-DOS mientras que el proceso sigue activo...
En ocasiones, dependiendo de qué se quiera ejecutar, nunca se detecta el fin de la actividad del proceso. En esos casos el bucle se convierte en infinito.
Por lo tanto, aconsejo a quien vaya a utilizar esos trucos, que incorpore en dicho bucle un Time-Out, el que cada cual estime más oportuno...

Por ejemplo..., éste es el bucle al que hago referencia en la solución aportada por kurono:
Código Delphi [-]
[...]
begin
[...]
        repeat
          PeekNamedPipe(read_stdout, @Buffer, SizeOf(Buffer) - 1, @bread, @avail, nil);
          if bread > 0 then
          begin
            Fillchar(Buffer, SizeOf(Buffer), 0);
            ReadFile(read_stdout, Buffer, bread, bread, nil);
            Result:= Result + String(PChar(@Buffer));
          end;
          Application.ProcessMessages;
          GetExitCodeProcess(pi.hProcess, exitcod);
        until (exitcod <> STILL_ACTIVE) and (bread = 0);
[...]
end;


Conviene declarar una variable TDateTime para controlar el tiempo transcurrido. Primero la inicializamos reflejando en ella el TimeOut a respetar, y luego añadimos el control del TimeOut dentro de la condición de salida del bucle.
Código Delphi [-]
var
  TimeOut : TDateTime;  // esta variable servirá para controlar el TimeOut
[...]
begin
[...]
        TimeOut := Now + EncodeTime(0,0,30,0);   // esto es un TimeOut de 30 segundos

        repeat
          PeekNamedPipe(read_stdout, @Buffer, SizeOf(Buffer) - 1, @bread, @avail, nil);
          if bread > 0 then
          begin
            Fillchar(Buffer, SizeOf(Buffer), 0);
            ReadFile(read_stdout, Buffer, bread, bread, nil);
            Result:= Result + String(PChar(@Buffer));
          end;
          Application.ProcessMessages;
          GetExitCodeProcess(pi.hProcess, exitcod);

        until ((exitcod <> STILL_ACTIVE) and (bread = 0))
           or (timeout < now);  // añadir esta condición para controlar el TimeOut
[...]
end;
Responder Con Cita
  #8  
Antiguo 26-01-2011
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Cita:
Empezado por Flecha Ver Mensaje
En ocasiones, dependiendo de qué se quiera ejecutar, nunca se detecta el fin de la actividad del proceso. En esos casos el bucle se convierte en infinito.
¿Podrías mencionar un caso en que suceda esto?

// Saludos
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 11:38:49.


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
Copyright 1996-2007 Club Delphi