Search code examples
delphidelphi-10.2-tokyo

Shellexecute equivalent for Linux as target platform


Does anyone knows the equivalent for Shellexecute command for Linux as active target platform?


Solution

  • Ended up wit this:

    const
       libc = '/usr/lib/libc.dylib';
    
    type
       PIOFile = Pointer;
    
       // Create a new stream connected to a pipe running the given command.
    function popen(const Command: PAnsiChar; Modes: PAnsiChar): PIOFile; cdecl; external libc name 'popen';
    
    // Close a stream opened by popen and return the status of its child.
    function pclose(Stream: PIOFile): Integer; cdecl; external libc name 'pclose';
    
    // Return the EOF indicator for STREAM.
    function feof(Stream: PIOFile): Integer; cdecl; external libc name 'feof';
    
    // Read chunks of generic data from STREAM.
    function fread(Ptr: Pointer; Size: LongWord; N: LongWord; Stream: PIOFile): LongWord; cdecl; external libc name 'fread';
    
    // Wait for a child to die.  When one does, put its status in *STAT_LOC
    // and return its process ID.  For errors, return (pid_t) -1.
    function wait(__stat_loc: PInteger): Integer; cdecl; external libc name 'wait';
    
    
    procedure TUtils.RunCommand(const CmdLine: string; results: TStrings);
    var
       Output: PIOFile;
       Buffer: PAnsiChar;
       TempString: Ansistring;
       Line: Ansistring;
       BytesRead: Integer;
    const
       BufferSize: Integer = 1000;
    begin
       TempString := '';
       Output := popen(PAnsiChar(Ansistring(CmdLine)), 'r');
       GetMem(Buffer, BufferSize);
       if Assigned(Output) then
          try
             while feof(Output) = 0 do
             begin
                BytesRead := fread(Buffer, 1, BufferSize, Output);
                SetLength(TempString, Length(TempString) + BytesRead);
                Move(Buffer^, TempString[Length(TempString) - (BytesRead - 1)], BytesRead);
    
                while Pos(#10, TempString) > 0 do
                begin
                   Line := Copy(TempString, 1, Pos(#10, TempString) - 1);
                   results.Add(UTF8ToString(Line));
    
                   TempString := Copy(TempString, Pos(#10, TempString) + 1, Length(TempString));
                end;
             end;
          finally
             pclose(Output);
             wait(nil);
           FreeMem(Buffer, BufferSize);
          end;
    end;