Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   C++ Builder (https://www.clubdelphi.com/foros/forumdisplay.php?f=13)
-   -   una mas, capturar el resultado del system() (https://www.clubdelphi.com/foros/showthread.php?t=61450)

Negriz 07-11-2008 23:08:32

una mas, capturar el resultado del system()
 
ho,a como estan...
esta nueva pregutna es para saber si puedo guardar en una variable el resultado de los comandos que ejecuto desde system(); para ser mas claro supongamos que uso al presionar un boton:

Cita:

system("dir C:")
esto me mostraria abriria una consola diciendo algo mas o menos asi:



bueno lo que quiero saber es que si el resultado de ese dir, osea el listado de directorios que muestra puede ser alamacenado en una variable o algo asi...

Gracias

cHackAll 08-11-2008 00:28:57

Esto lo puedes abordar "redireccionando"... por ejemplo abre la consola y pega ésto:

Código:

dir %systemroot%\*.* /s /b > %temp%\filelist.txt&notepad %temp%\filelist.txt
El anterior ejemplo te guarda en un archivo el resultado del comando "dir" y lo abre con el Bloc de notas.

Tambien puedes revisar ésto.

Saludos

escafandra 08-11-2008 03:17:14

También te resultará interesante.

Saludos.

Negriz 08-11-2008 18:34:56

ya habia pensado en lo del TXT pero me parecio interesnte preguntar acerca de metodos alternativos...

Muhas gracias, aunqeu no soy muy bueno en delphi esto me ayuda a comprender y aprender un poco mas del enguaje voy a mirar y muchas gracias de nuevo :D :D.

Negriz 12-11-2008 01:04:58

hola...
encontre "GetDosOutput" pero no encontre como utilizarla en c++ Builder...

tambien utilize: system( "taskkill /M taskmgr.exe > %tmp%//kill.txt" );
y funciona bien pero me muestra la consola, cosa que no deseo....
despues utilize:
ShellExecute(0, "open", "taskkill","/IM taskmgr.exe", "%SystemDir%//System32", SW_HIDE);
no se como capturar el resultado, es ceri no se donde poner "> %tmp%//kill.txt" ya que es un comando mas.
despues intente con:
WinExec( "taskkill /M taskmgr.exe > %tmp%//kill.txt", SW_HIDE)
modifique SW_HIDE por SW_NORMAL para poder ver el resultado y me decia que los parametros eran incorrectos...

entonces mi pregunta es como hago esto con shellexecute o WinExec para que funcione ya que estos dos me dejan esconder la consola de commandos

Gracias.

escafandra 12-11-2008 21:04:42

Crea un archivo que se llame consoleoutput.pas
En él escribe:

Código Delphi [-]
  
unit consoleoutput;

interface

uses
  Controls, Windows, SysUtils, Forms;

function GetDosOutput(CommandLine:string): string;
function ExecuteDOSCommand(CommandLine:string): string;

//---------------------------------------------------------------------------
implementation
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Ejecuta y devuelve el resultado de un comando DOS o de consola
// sin usar la ruta específica del mismo
// No se pueden ejecutar procesos que no sean del S.O.
function ExecuteDOSCommand(CommandLine:string): string;
var
  cmdbuffer: Array [0..MAX_PATH] of Char;

begin
  GetEnvironmentVariable( 'COMSPEC', cmdBUffer, Sizeof(cmdBuffer));
  CommandLine := cmdbuffer + ' /C ' + CommandLine;
//  Result := (CommandLine);
  Result := GetDosOutput(CommandLine);
end;

//---------------------------------------------------------------------------
// Ejecuta y devuelve el resultado de un proceso por linea de comandoso de consola
// Necesita la ruta especifica del proceso
function GetDosOutput(CommandLine:string): string;
var
  SA: TSecurityAttributes;
  SI: TStartupInfo;
  PI: TProcessInformation;
  StdOutPipeRead, StdOutPipeWrite: THandle;
  WasOK: Boolean;
  Buffer: array[0..255] of Char;
  BytesRead: Cardinal;
  WorkDir, Line: String;
begin
  Application.ProcessMessages;
  with SA do
  begin
    nLength := SizeOf(SA);
    bInheritHandle := True;
    lpSecurityDescriptor := nil;
  end;
  // create pipe for standard output redirection
  CreatePipe(StdOutPipeRead,  // read handle
             StdOutPipeWrite, // write handle
             @SA,             // security attributes
             0                // number of bytes reserved for pipe - 0 default
             );
  try
    // Make child process use StdOutPipeWrite as standard out,
    // and make sure it does not show on screen.
    with SI do
    begin
      FillChar(SI, SizeOf(SI), 0);
      cb := SizeOf(SI);
      dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE;
      hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect std input
      hStdOutput := StdOutPipeWrite;
      hStdError := StdOutPipeWrite;
    end;

    // launch the command line compiler
    WorkDir := ExtractFilePath(CommandLine);
    WasOK := CreateProcess(nil, PChar(CommandLine), nil, nil, True, 0, nil, PChar(WorkDir), SI, PI);

    // Now that the handle has been inherited, close write to be safe.
    // We don't want to read or write to it accidentally.
    CloseHandle(StdOutPipeWrite);
    // if process could be created then handle its output
    if not WasOK then
      raise Exception.Create('Could not execute command line!')
    else
      try
        // get all output until dos app finishes
        Line := '';
        repeat
          // read block of characters (might contain carriage returns and line feeds)
          WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);

          // has anything been read?
          if BytesRead > 0 then
          begin
            // finish buffer to PChar
            Buffer[BytesRead] := #0;
            // combine the buffer with the rest of the last run
            Line := Line + Buffer;
          end;
        until not WasOK or (BytesRead = 0);
        // wait for console app to finish (should be already at this point)
        WaitForSingleObject(PI.hProcess, INFINITE);
      finally
        // Close all remaining handles
        CloseHandle(PI.hThread);
        CloseHandle(PI.hProcess);
      end;
  finally
      result:=Line;
      CloseHandle(StdOutPipeRead);
  end;
end;


end.

Añádelo a tu proyecto Builder y compílalo por separado. Generará un archivo llamado consoleoutput.hpp, es la cabecera de las dos funciones.

Incluye esa cabecera en las unidades .cpp donde quieras usar las funciones, y compila.

Saludos.

Negriz 13-11-2008 20:01:30

:eek::eek::eek:no sabia que eso se podia hacer...

mira funciona bien lo que me digiste, me crea el hpp pero hay un prblema,
la funcion ExecuteDOSCommnad no pueed ejecutar mas de un comando, ejemplo help>c:/a.txt produce una excepcion y la funcion GetDosOutput no funciona con ningun cmando... Que puedo hacer.?

escafandra 14-11-2008 01:15:19

Esas funciones devuelven un Sring, de forma que no te hace falta redireccionar el flujo a un archivo de texto, que creo era la idea original:rolleyes:. Tu programa lee directamente el resultado en una cadena:

Código:

AnsiString Help = ExecuteDOSCommand("help");
Carga en Help el resultado del comando help
Para cada comando, una llamada nueva.
Tiene ciertas limitaciones y se puede mejorar....

ExecuteDOSCommand Sólo ejecuta comandos del Sistema Operativo, y no precisa de la ruta completa del comando.

GetDosOutput requiere la ruta completa del proceso a ejecutar. Es utlizada por ExecuteDOSCommand para llamar al comando requerido.

Saludos.

Negriz 14-11-2008 16:42:22

Muchas Gracias... :D:D:D
 
Entiendo, (no puedo creer que no la haya pillado :o) no tengo que usar GetDosCommand :)

:):):) muchas gracias por la ayuda.


La franja horaria es GMT +2. Ahora son las 10:16:39.

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