2017-03-25 26 views
0

私はOSXを使用していますが、次のDelphi(Firemonkey)コードでコンソール出力をメモに書き込むことができました。これは、 "ls"のような通常のコマンドを使用しているときにうまく動作しますが、外部端末のアプリケーションからの出力をキャプチャしません。Delphi:OSXコンソール出力のキャプチャ

たとえば、コマンドラインアプリケーション "youtube-dl"を実行すると、出力はPAServerログにのみ表示されますが、メモには表示されません。

これを行う方法はありますか?あるいは、誰かがこのコードを修正してこの作業をすることができますか?

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 TForm1.ExecCmdine(const CmdLine: string); 
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); 
      Memo1.Lines.Add(UTF8ToString(Line)); 

     TempString := Copy(TempString, Pos(#10, TempString) + 1, Length(TempString)); 
     end; 
    end; 
    finally 
    pclose(output); 
    wait(nil); 
    FreeMem(Buffer, BufferSize); 
    end; 
end; 
+0

出力から何かが得られますか?もしそうなら...なぜcmdresultが必要なのでしょうか? utf8tostringは空の文字列を返しませんか? (無効なcharコードのため)?すべてのブランチに対してユニットテストを行います。 –

+0

私が実行したコマンド(youtube-dl)は動作し、ビデオはダウンロードされますが、コンソール出力とは別のことをしたいと思います。例えば、プロセスバーや、私は利用可能なビデオフォーマットを見たいなどです。私は、テスト目的のためにPos(#10、TempString)> 0 do "のwhileループでshowmessage( 'test')を追加したので、utf8tostringが問題ではないと思います。 whileループは決して真実ではないようです。 – Chris

+0

は連結を簡単にしました。 tempString:= tempString + strPas(buffer ^) –

答えて

0

ロブ・ケネディは正解でしたが、悲しいことに彼は答えとして投稿しなかったので、私はそれを行います。

問題は、youtube-dlのコンソール出力が標準出力ではなくstderrに出力されるため、実行時にconsoleコマンドに2> & 1を追加しなければならないということでした。

関連する問題