Capturar saída do DOS

Delphi

21/07/2023

alguém sabe como capturar a saída de um comando no DOS e passar ele para um memo?
Paulo Oliveira

Paulo Oliveira

Curtidas 0

Respostas

Paulo Oliveira

Paulo Oliveira

21/07/2023

alguém sabe como capturar a saída de um comando no DOS e passar ele para um memo?


tentei utilizar isso:

DOS - roda um comando dos e captura saida num memo
Top Previous Next
// roda um comando dos e captura saida num memo

{

This function runs a program (console or batch) and adds its output

to Memo1

}



{....}

// private

// function RunCaptured(const _dirName, _exeName, _cmdLine: string): Boolean;



{....}



function TForm1.RunCaptured(const _dirName, _exeName, _cmdLine: string): Boolean;

var

start: TStartupInfo;

procInfo: TProcessInformation;

tmpName: string;

tmp: Windows.THandle;

tmpSec: TSecurityAttributes;

res: TStringList;

return: Cardinal;

begin

Result := False;

try

// set a temporary file

tmpName := 'Test.tmp';

FillChar(tmpSec, SizeOf(tmpSec), #0);

tmpSec.nLength := SizeOf(tmpSec);

tmpSec.bInheritHandle := True;

tmp := Windows.CreateFile(PChar(tmpName),

Generic_Write, File_Share_Write,

@tmpSec, Create_Always, File_Attribute_Normal, 0);

try

FillChar(start, SizeOf(start), #0);

start.cb := SizeOf(start);

start.hStdOutput := tmp;

start.dwFlags := StartF_UseStdHandles or StartF_UseShowWindow;

start.wShowWindow := SW_Minimize;

// Start the program

if CreateProcess(nil, PChar(_exeName + ' ' + _cmdLine), nil, nil, True,

0, nil, PChar(_dirName), start, procInfo) then

begin

SetPriorityClass(procInfo.hProcess, Idle_Priority_Class);

WaitForSingleObject(procInfo.hProcess, Infinite);

GetExitCodeProcess(procInfo.hProcess, return);

Result := (return = 0);

CloseHandle(procInfo.hThread);

CloseHandle(procInfo.hProcess);

Windows.CloseHandle(tmp);

// Add the output

res := TStringList.Create;

try

res.LoadFromFile(tmpName);

Memo1.Lines.AddStrings(res);

finally

res.Free;

end;

Windows.DeleteFile(PChar(tmpName));

end

else

Application.MessageBox(PChar(SysErrorMessage(GetLastError())), 'RunCaptured Error', MB_OK);

except

Windows.CloseHandle(tmp);

Windows.DeleteFile(PChar(tmpName));

raise;

end;

finally

end;

end;



// Example:

procedure TForm1.Button1Click(Sender: TObject);

begin

RunCaptured('C:\\', 'cmd.exe', '/c dir');

end;

porém retorna o erro E2096 e E2066
GOSTEI 0
Arthur Heinrich

Arthur Heinrich

21/07/2023

Eu tenho uma rotina para isso:

procedure RunDosCommand(DosApp:String; Result : TStrings);
const
  ReadBuffer = 2400;
var
  Security : TSecurityAttributes;
  ReadPipe,WritePipe : THandle;
  start : TStartUpInfo;
  ProcessInfo : TProcessInformation;
  Buffer : Pchar;
  BytesRead : DWord;
  Apprunning : DWord;
begin
  with Security do
    begin
      nlength := SizeOf(TSecurityAttributes) ;
      binherithandle := true;
      lpsecuritydescriptor := nil;
    end;
  if Createpipe (ReadPipe, WritePipe,@Security, 0)
    then
      begin
        Buffer := AllocMem(ReadBuffer + 1) ;
        FillChar(Start,Sizeof(Start),#0) ;
        start.cb := SizeOf(start) ;
        start.hStdOutput := WritePipe;
        start.hStdInput := ReadPipe;
        start.dwFlags := STARTF_USESTDHANDLES +STARTF_USESHOWWINDOW;
        start.wShowWindow := SW_HIDE;
        if CreateProcess(nil,PChar(DosApp),@Security,@Security,true,
                         NORMAL_PRIORITY_CLASS,nil,nil,start,ProcessInfo)
          then
            repeat
              Apprunning := WaitForSingleObject(ProcessInfo.hProcess,100) ;
              Application.ProcessMessages;
              BytesRead := 0;
              ReadFile(ReadPipe,Buffer[0],ReadBuffer,BytesRead,nil) ;
              Buffer[BytesRead]:= #0;
              OemToAnsi(Buffer,Buffer) ;
              Result.Text := Result.text + String(Buffer) ;
            until (Apprunning <> WAIT_TIMEOUT) ;
        FreeMem(Buffer) ;
        CloseHandle(ProcessInfo.hProcess) ;
        CloseHandle(ProcessInfo.hThread) ;
        CloseHandle(ReadPipe) ;
        CloseHandle(WritePipe) ;
      end;
end;

GOSTEI 0
POSTAR