Ver Mensaje Individual
  #7  
Antiguo 22-03-2007
Avatar de ArdiIIa
[ArdiIIa] ArdiIIa is offline
Miembro Premium
 
Registrado: nov 2003
Ubicación: Valencia city
Posts: 1.481
Reputación: 22
ArdiIIa Va por buen camino
Hola y perdón por la intromisión.
Yo hace tiempo que utilicé esa técnica con varios motores de ajedrez, a los que les mandaba diferentes comandos , esperaba su respuesta y teniendo un control absoluto sobre la entrada y salida...


Código Delphi [-]
procedure TFormMain.Launch(cmdline : string; ShowWindow : integer);
var ProcessInfo : TProcessInformation;
    StartupInfo : TStartupInfo;
begin
    CreatePipe(hOutReadPipe, hOutWritePipe, nil, 2024);
    DuplicateHandle(GetCurrentProcess(),
                              hOutWritePipe,  GetCurrentProcess(),
                              @hDupWritePipe, 0, True,
DUPLICATE_CLOSE_SOURCE or  DUPLICATE_SAME_ACCESS);

    CreatePipe(hInReadPipe, hInWritePipe, nil, 2024);
    DuplicateHandle(GetCurrentProcess(),
hInReadPipe,GetCurrentProcess(),
                    @hDupReadPipe, 0, True, DUPLICATE_CLOSE_SOURCE or
DUPLICATE_SAME_ACCESS);


  FillChar(StartupInfo,Sizeof(StartupInfo),#0);
  StartupInfo.cb := Sizeof(StartupInfo);
  StartupInfo.hStdOutput := hDupWritePipe;
  StartupInfo.hStdError  := hDupWritePipe;
  StartupInfo.hStdInput  := hDupReadPipe;
  StartupInfo.wShowWindow := ShowWindow;
  StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;

  CreateProcess(nil, PChar(cmdline), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil,StartupInfo, ProcessInfo);

end;


Luego un par de funciones accesorias de control

Código Delphi [-]
function TFormMain.ReadPipe(var S : string): Boolean;
var
  dwAvail, dwRead : Cardinal;
  PipeHandle : THandle;
begin
  Result := False;
  PipeHandle := hOutReadPipe;
  dwAvail := 0;
  PeekNamedPipe(PipeHandle, nil, 0, nil, @dwAvail, nil);
  if dwAvail > 0 then
  begin
    SetLength(S, dwAvail);
    ReadFile(PipeHandle, Pointer(S)^, dwAvail, dwRead, nil);
    Result := True;
  end;
  Application.ProcessMessages;
end;

procedure TFormMain.WritePipe(s: string);
var Pstr : array[0..255] of char;
    len : cardinal;
    PipeHandle : THandle;
begin
  PipeHandle := hInWritePipe;
  StrPCopy(Pstr, s);
  len := length(s);
  WriteFile(PipeHandle, Pstr, len, len, nil);
  Sleep(10);
end;



Otra alternativa es esta:


Código Delphi [-]


{---------------------------CreateDOSProcessRedirected--------------------------
 Description    : executes a (DOS!) app defined in the CommandLine parameter
                  redirected to take input from InputFile (optional) and give
                  output to OutputFile
 Result         : True on success
 Parameters     : CommandLine : the command line for app, including full path
                  InputFile   : the ascii file where from the app takes input,
                                 empty if no input needed/required.
                  OutputFile  : the ascii file to which the output is redirected
                  ErrMsg      : additional error message string. Can be empty
 Error checking : YES
 Target         : Delphi 2, 3, 4
 Author         : Theodoros Bebekis, email bebekis@otenet.gr
 Notes          :
 Example call   : CreateDOSProcessRedirected('C:\MyDOSApp.exe',
                                             'C:\InputPut.txt',
                                             'C:\OutPut.txt',
                                             'Please, record this message')
-------------------------------------------------------------------------------}

function TFormMain.CreateDOSProcessRedirected(const CommandLine, InputFile,OutputFile: string): boolean;
var OldCursor: TCursor;
    pCommandLine: array[0..MAX_PATH] of char;
    pInputFile, pOutPutFile: array[0..MAX_PATH] of char;
    StartupInfo: TStartupInfo;
    ProcessInfo: TProcessInformation;
    SecAtrrs: TSecurityAttributes;
    hAppProcess, hAppThread, hInputFile, hOutputFile: THandle;
begin
  result := false;
  if ((InputFile <> '') and (not fileexists(InputFile))) then exit;
  hAppProcess := 0;
  hAppThread := 0;
  hInputFile := 0;
  hOutputFile := 0;
  OldCursor := Screen.Cursor;
  Screen.Cursor := crHourglass;
  try
    StrPCopy(pCommandLine, CommandLine);
    StrPCopy(pInputFile, InputFile);
    StrPCopy(pOutPutFile, OutputFile);
    FillChar(SecAtrrs, SizeOf(SecAtrrs), #0);
    SecAtrrs.nLength := SizeOf(SecAtrrs);
    SecAtrrs.lpSecurityDescriptor := nil;
    SecAtrrs.bInheritHandle := true;
    if (InputFile <> '') then
    begin
      hInputFile := CreateFile(pInputFile, GENERIC_READ or GENERIC_WRITE,
         FILE_SHARE_READ or FILE_SHARE_WRITE, @SecAtrrs, OPEN_ALWAYS,
         FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH, 0);
      if (hInputFile = INVALID_HANDLE_VALUE) then exit;
    end else hInputFile := 0;
    hOutputFile := CreateFile(pOutPutFile, GENERIC_READ or GENERIC_WRITE,
       FILE_SHARE_READ or FILE_SHARE_WRITE, @SecAtrrs, CREATE_ALWAYS,
       FILE_ATTRIBUTE_NORMAL or FILE_FLAG_WRITE_THROUGH, 0);
    if (hOutputFile = INVALID_HANDLE_VALUE) then exit;
    FillChar(StartupInfo, SizeOf(StartupInfo), #0);
    StartupInfo.cb := SizeOf(StartupInfo);
    StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    StartupInfo.wShowWindow := SW_HIDE;
    StartupInfo.hStdOutput := hOutputFile;
    StartupInfo.hStdInput := hInputFile;
    Application.ProcessMessages;
    result := CreateProcess(nil, pCommandLine, nil, nil, TRUE,
                            HIGH_PRIORITY_CLASS  ,
                            nil, nil, StartupInfo, ProcessInfo);
    Application.ProcessMessages;
    if (result) then
    begin
      WaitforSingleObject(ProcessInfo.hProcess, INFINITE);
      hAppProcess := ProcessInfo.hProcess;
      hAppThread := ProcessInfo.hThread;
    end else exit;
  finally
    Application.ProcessMessages;
    if (hOutputFile <> 0) then CloseHandle(hOutputFile);
    if (hInputFile <> 0) then CloseHandle(hInputFile);
    if (hAppThread <> 0) then CloseHandle(hAppThread);
    if (hAppProcess <> 0) then CloseHandle(hAppProcess);
    Screen.Cursor := OldCursor;
  end;
end;


Uno de los casos en los que también lo utilicé, fue para ejecutar y leer el comando NETSTAT. Pena que cuando me hacía falta, seoane todavía no había insertado su código su post, y a mí me hacía falta hace tiempo
__________________
Un poco de tu generosidad puede salvar la vida a un niño. ASÍ DE SENCILLO
Responder Con Cita