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-lazarushttps://www.tek-tips.com/forums/102/faqs/7402I 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.
constructor TSTDIOMonitor.Create(AOwner: TComponent);
var
Security: TSecurityAttributes;
begin
inherited Create(AOwner);
with Security do
begin
nlength := SizeOf(TSecurityAttributes) ;
binherithandle := true;
lpsecuritydescriptor := nil;
end;
CreatePipe(InputPipeRead, InputPipeWrite, @Security, 0);
CreatePipe(OutputPipeRead, OutputPipeWrite, @Security, 0);
CreatePipe(ErrorPipeRead, ErrorPipeWrite, @Security, 0);
SetStdHandle(STD_INPUT_HANDLE, InputPipeRead);
SetStdHandle(STD_OUTPUT_HANDLE, OutputPipeWrite);
SetStdHandle(STD_ERROR_HANDLE, ErrorPipeWrite);
FStringList := TStringList.Create;
ReadThread := TReadThread.Create;
ReadThread.Enabled := False;
ReadThread.StringList := FStringList;
ReadThread.OnUpdate := @DoUpdate;
ReadThread.Start;
end;
procedure TReadThread.Execute;
var
BytesRem: Integer;
begin
while not Terminated do
begin
if FEnabled then
begin
BytesRem := 0;
FTextString := ReadPipeInput(OutputPipeRead, BytesRem);
if FTextString <> '' then
Synchronize(@DoUpdate);
FTextString := ReadPipeInput(ErrorPipeRead, BytesRem);
if FTextString <> '' then
Synchronize(@DoUpdate);
end;
sleep(40);
end;
end;
function ReadPipeInput(aInputPipe: THandle; var aBytesRem: Integer): String;
var
vTextBuffer: array[1..32767] of char;
vTextString: String;
vBytesRead: DWORD;
vPipeSize: Integer;
begin
Result := '';
vPipeSize := Sizeof(vTextBuffer);
PeekNamedPipe(aInputPipe, nil, vPipeSize, @vBytesRead, @vPipeSize, @aBytesRem);
if vBytesRead > 0 then
begin
ReadFile(aInputPipe, vTextBuffer, vPipeSize, vBytesRead, nil);
OemToChar(@vTextBuffer, @vTextBuffer);
vTextString := String(vTextBuffer);
SetLength(vTextString, vBytesRead);
Result := vTextString;
end;
end;
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