[LINUX] Executar uma linha de comando

81 views
Skip to first unread message

Anderson Dapper

unread,
Sep 24, 2017, 6:11:14 AM9/24/17
to dugrs
Pessoal,

Estou desenvolvendo algumas ferramentas para Linux usando o Delphi Tokyo e tive o problema de não conseguia de forma alguma fazer chamadas e comandos externos.

Então percorri a internet e achei o seguinte site http://chapmanworld.com/2017/04/06/calling-linux-commands-from-delphi/ 

Mas isso ainda não me era suficiente pois a forma que o código estava implementado me forçava a usar um tal de MarshaledString.

Consegui fazer um codigo bacana depois de umas horas testando e batendo no código (a vontade não falta quando não funciona como a gente quer) 

Vou compartilhar com vocês pois foi bem complicado ter essa informação e difícil de acha-la

Segue o código:


uses
  System.SysUtils,
  System.Classes,
  Posix.Base,
  Posix.Fcntl;

type
  TStreamHandle = pointer;

  TLinuxUtils = class
  public
class function RunCommandLine(ACommand : string) : TStringList;overload;
class function RunCommandLine(Acommand : string; Return : TProc<String>) : boolean; overload;
  end;



  function popen(const command: MarshaledAString; const _type: MarshaledAString): TStreamHandle; cdecl; external libc name _PU + 'popen';
  function pclose(filehandle: TStreamHandle): int32; cdecl; external libc name _PU + 'pclose';
  function fgets(buffer: pointer; size: int32; Stream: TStreamHAndle): pointer; cdecl; external libc name _PU + 'fgets';


implementation

class function TLinuxUtils.RunCommandLine(ACommand : string) : TStringList;
var
  Handle: TStreamHandle;
  Data: array[0..511] of uint8;
  M : TMarshaller;

begin
  Result := TStringList.Create;
  try
Handle := popen(M.AsAnsi(PWideChar(ACommand)).ToPointer,'r');
try
 while fgets(@data[0],Sizeof(Data),Handle)<>nil do begin
Result.Add(Copy(UTF8ToString(@Data[0]),1,UTF8ToString(@Data[0]).Length -1));
 end;
finally
 pclose(Handle);
end;
  except
on E: Exception do
 Result.Add(E.ClassName + ': ' + E.Message);
  end;
end;

class function TLinuxUtils.RunCommandLine(Acommand : string; Return : TProc<string>) : boolean;
var
  Handle: TStreamHandle;
  Data: array[0..511] of uint8;
  M : TMarshaller;

begin
  Result := false;
  try
Handle := popen(M.AsAnsi(PWideChar(ACommand)).ToPointer,'r');
try
 while fgets(@data[0],Sizeof(Data),Handle)<>nil do begin
Return(Copy(UTF8ToString(@Data[0]),1,UTF8ToString(@Data[0]).Length -1));
 end;
finally
 pclose(Handle);
end;
  except
on E: Exception do
 Return(E.ClassName + ': ' + E.Message);
  end;
end;




Att,
Anderson Dapper Rocha
Reply all
Reply to author
Forward
0 new messages