Recent

Author Topic: Stdout from program  (Read 15043 times)

tomek

  • Jr. Member
  • **
  • Posts: 85
Stdout from program
« on: March 08, 2011, 09:53:51 pm »
Is there any way to catch/redirect stdout of program in program ?
I want to get like debugln messages in my app (as ex. in Memo component) ? Something like catch self stdout.

eny

  • Hero Member
  • *****
  • Posts: 1646
Re: Stdout from program
« Reply #1 on: March 08, 2011, 10:13:04 pm »
All posts based on: Win10 (Win64); Lazarus 3_4  (x64) 25-05-2024 (unless specified otherwise...)

Leledumbo

  • Hero Member
  • *****
  • Posts: 8783
  • Programming + Glam Metal + Tae Kwon Do = Me

tomek

  • Jr. Member
  • **
  • Posts: 85
Re: Stdout from program
« Reply #3 on: March 09, 2011, 08:15:17 am »
@leledumbo, you do not understand me, I want to catch self output.

@eny, thanks for hint, but it doesn't work, I also try with:
Code: [Select]
GetStdHandle(STD_OUTPUT_HANDLE)
 ReadConsoleOutputCharacter
and it's work only with nogui app (without -WG) or if I use AllocConsole before GetStdHandle(STD_OUTPUT_HANDLE).
It seams that it will work only with console.
I wonder how can help  --debug-log application parameter, which probably redirects STDOUT.
« Last Edit: March 09, 2011, 08:24:21 am by tomek »

eny

  • Hero Member
  • *****
  • Posts: 1646
Re: Stdout from program
« Reply #4 on: March 09, 2011, 09:59:14 am »
The question is: why do want to access stdout?
If it's for logging purposes it might be better to use a logging package like log4delphi (which has a FPC port).
All posts based on: Win10 (Win64); Lazarus 3_4  (x64) 25-05-2024 (unless specified otherwise...)

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1930
Re: Stdout from program
« Reply #5 on: March 09, 2011, 10:19:58 am »

tomek

  • Jr. Member
  • **
  • Posts: 85
Re: Stdout from program
« Reply #6 on: March 09, 2011, 10:21:03 am »
The question is: why do want to access stdout?
...

I use dll in the program, that dll provides only output as "print to stdout". And I want to have this output in gui app (without console). That's the problem.

eny

  • Hero Member
  • *****
  • Posts: 1646
All posts based on: Win10 (Win64); Lazarus 3_4  (x64) 25-05-2024 (unless specified otherwise...)

tomek

  • Jr. Member
  • **
  • Posts: 85
Re: Stdout from program
« Reply #8 on: March 09, 2011, 12:48:40 pm »
Google reveals this link: http://stackoverflow.com/questions/2639144/delphi-capture-stdout-and-stderr-output-from-statically-linked-msvc-compiled
That might help.

THANKS. That's it.
I use with Pipe, CreatePipe and SetStdHandle(STD_OUTPUT_HANDLE, hWriteToPipe) and I have output wherever I want.  :)

mirco

  • Newbie
  • Posts: 3
Re: Stdout from program
« Reply #9 on: May 17, 2017, 06:44:46 am »
Quote
I use with Pipe, CreatePipe and SetStdHandle(STD_OUTPUT_HANDLE, hWriteToPipe) and I have output wherever I want.  :)
Could you share your solution, please?
Thank you.

Gyuri

  • New member
  • *
  • Posts: 7
Re: Stdout from program
« Reply #10 on: December 11, 2024, 03:16:13 pm »
Hello forum members,

For some reason I can't create a new topic, so I am continuing here, since I found it the most appropriate to my problem.

I am using a 32 bit dll on 64 bit Windows. The dll is sending status information to stdout. With inspiration from this topic, and these two:
https://stackoverflow.com/questions/43291343/receive-and-handle-windows-messages-in-lazarus
https://www.tek-tips.com/forums/102/faqs/7402

I was able to "capture/redirect" the stdout, and be able to process it with my GUI application. I used pipes, and read in a thread. Here is the code snippet (full code of the monitor unit attached in the zip archive) of the creation and read function.
Code: Pascal  [Select][+][-]
  1. constructor TSTDIOMonitor.Create(AOwner: TComponent);
  2. var
  3.   Security: TSecurityAttributes;
  4. begin
  5.   inherited Create(AOwner);
  6.   with Security do
  7.   begin
  8.     nlength := SizeOf(TSecurityAttributes) ;
  9.     binherithandle := true;
  10.     lpsecuritydescriptor := nil;
  11.   end;
  12.   CreatePipe(InputPipeRead, InputPipeWrite, @Security, 0);
  13.   CreatePipe(OutputPipeRead, OutputPipeWrite, @Security, 0);
  14.   CreatePipe(ErrorPipeRead, ErrorPipeWrite, @Security, 0);
  15.   SetStdHandle(STD_INPUT_HANDLE, InputPipeRead);
  16.   SetStdHandle(STD_OUTPUT_HANDLE, OutputPipeWrite);
  17.   SetStdHandle(STD_ERROR_HANDLE, ErrorPipeWrite);
  18.   FStringList := TStringList.Create;
  19.   ReadThread  := TReadThread.Create;
  20.   ReadThread.Enabled    := False;
  21.   ReadThread.StringList := FStringList;
  22.   ReadThread.OnUpdate   := @DoUpdate;
  23.   ReadThread.Start;
  24. end;
  25.  
Code: Pascal  [Select][+][-]
  1. procedure TReadThread.Execute;
  2. var
  3.   BytesRem: Integer;
  4. begin
  5.   while not Terminated do
  6.   begin
  7.     if FEnabled then
  8.     begin
  9.       BytesRem := 0;
  10.       FTextString := ReadPipeInput(OutputPipeRead, BytesRem);
  11.       if FTextString <> '' then
  12.          Synchronize(@DoUpdate);
  13.       FTextString := ReadPipeInput(ErrorPipeRead, BytesRem);
  14.       if FTextString <> '' then
  15.          Synchronize(@DoUpdate);
  16.     end;
  17.     sleep(40);
  18.   end;
  19. end;
  20.  
Code: Pascal  [Select][+][-]
  1. function ReadPipeInput(aInputPipe: THandle; var aBytesRem: Integer): String;
  2. var
  3.   vTextBuffer: array[1..32767] of char;
  4.   vTextString: String;
  5.   vBytesRead: DWORD;
  6.   vPipeSize: Integer;
  7. begin
  8.   Result := '';
  9.   vPipeSize := Sizeof(vTextBuffer);
  10.   PeekNamedPipe(aInputPipe, nil, vPipeSize, @vBytesRead, @vPipeSize, @aBytesRem);
  11.   if vBytesRead > 0 then
  12.   begin
  13.     ReadFile(aInputPipe, vTextBuffer, vPipeSize, vBytesRead, nil);
  14.     OemToChar(@vTextBuffer, @vTextBuffer);
  15.     vTextString := String(vTextBuffer);
  16.     SetLength(vTextString, vBytesRead);
  17.     Result := vTextString;
  18.   end;
  19. end;
  20.  

Everything was fine as long I was running the application from the IDE. Accessing the dll's functions is also working fine, I receive all the necessary status information. I had the greatest surprise, when I started my application directly from the Windows environment. The stdio redirection/capturing is not working. Obviously I am making an elementary mistake, but it seems  am not able to find it.

I would really appreciate your help.

Thanks in advance,
Gyorgy

PS, also for some unknown reasons, I am not able to attach the zip archive
using Lazarus 1.4RC, FPC version 2.6.4,SVN rev 48058, Windows XP SP3/32bit, Windows7 SP1/64bit

 

TinyPortal © 2005-2018