Lazarus

Programming => Operating Systems => Windows => Topic started by: loaded on January 28, 2022, 02:26:03 pm

Title: [Solved] How is the pipeline transferred?
Post by: loaded on January 28, 2022, 02:26:03 pm
Hi All,
How can we import the pipeline used in the command line in windows not into a file but into a memo?
Title: Re: How is the pipeline transferred?
Post by: paweld on January 28, 2022, 03:13:58 pm
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. const
  3.   BufSize = 256;
  4. var
  5.   cmdprocess: TProcessUTF8;
  6.   ms: TMemoryStream;
  7.   NumBytes, BytesRead: Longint;
  8. begin
  9.   BytesRead := 0;
  10.   NumBytes := 0;
  11.   ms := TMemoryStream.Create;
  12.   cmdprocess := TProcessUTF8.Create(nil);
  13.   cmdprocess.Options := [poUsePipes, poNoConsole];
  14.   cmdprocess.Executable := 'cmd';
  15.   cmdprocess.Parameters.Add('/c');
  16.   cmdprocess.Parameters.Add('dir');
  17.   cmdprocess.Execute;
  18.   while cmdprocess.Running do
  19.   begin
  20.     ms.SetSize(BytesRead + BufSize);
  21.     NumBytes := cmdprocess.Output.Read((ms.Memory + BytesRead)^, BufSize);
  22.     if NumBytes > 0 then
  23.       Inc(BytesRead, NumBytes)
  24.     else
  25.       break;
  26.   end;
  27.   ms.SetSize(BytesRead);
  28.   memo1.Lines.LoadFromStream(ms);
  29.   ms.Free;
  30.   cmdprocess.Free;
  31. end;      
More info: https://wiki.freepascal.org/Executing_External_Programs#Reading_large_output
You may also use: https://github.com/t-edson/UnTerminal
Title: Re: How is the pipeline transferred?
Post by: engkin on January 28, 2022, 03:21:38 pm
The command is:

Dir |yourApp

Simply check StdInputHandle in your app.
When used as above, StdInputHandle is not going to be 0.

To read the data, use Windows API

Or

use THandleStream.

Or

Assign the handle to a text variable, and use ReadLn

Edit:
Sample code:
Code: Pascal  [Select][+][-]
  1. var
  2.   s:string;
  3.   hs: THandleStream;
  4. begin
  5.   if StdInputHandle>0 then
  6.   begin
  7.     hs:=THandleStream.Create(StdInputHandle);
  8.     SetLength(s,hs.Size);
  9.     hs.Read(s[1],hs.Size);
  10.     memo1.Text:=s;
  11.  
Title: Re: How is the pipeline transferred?
Post by: MarkMLl on January 28, 2022, 03:24:12 pm
The easiest way is to read what's available from Input (i.e. the preopened text device). I've done that in the past but would need to check the detail.

The worst bit is getting your program to decide whether anything's actually being piped to it, or if it should e.g. rely on the standard dialog(u)e etc. to open a file.

MarkMLl


Title: Re: How is the pipeline transferred?
Post by: loaded on January 28, 2022, 06:08:06 pm
Thank you very much paweld and engkin and MarkMLl each for your replies.
Inspired by the code and ideas you sent, I did a trial run. It works fine for the dos environment.
I don't know if you have used it before!!! but not working with Ghostscript app !!!
Is there anything else I can do about this? I would be glad if you can help. Respects.
Title: Re: How is the pipeline transferred?
Post by: engkin on January 28, 2022, 06:42:01 pm
Use the command line version.

I used GhostScript a few years ago, specifically I used the DLL.

Edit:
The command line version ends with the letter c.
Title: Re: How is the pipeline transferred?
Post by: loaded on January 28, 2022, 07:30:21 pm
The command line version ends with the letter c.
Perfect spot, thank you very much engkin
Title: Re: How is the pipeline transferred?
Post by: ASBzone on February 07, 2022, 10:37:24 pm
When used as above, StdInputHandle is not going to be 0.

The problem is that StdInputHandle is often not 0, even when no piping is taking place.

Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC}
  3.  
  4. program OpenPipe;
  5.  
  6. begin
  7.   WriteLn('Standard Input Handle Value is: ', StdInputHandle);
  8. end.
  9.  

Try this in Windows with the following commands:

MyExe.exe
DIR C:\ | MyExe.exe
Title: Re: [Solved] How is the pipeline transferred?
Post by: ASBzone on February 07, 2022, 10:59:07 pm
Also consider:  https://forum.lazarus.freepascal.org/index.php?topic=41936.0
Title: Re: How is the pipeline transferred?
Post by: engkin on February 08, 2022, 12:20:05 am
When used as above, StdInputHandle is not going to be 0.

The problem is that StdInputHandle is often not 0, even when no piping is taking place.

Code: Pascal  [Select][+][-]
  1. {$APPTYPE CONSOLE}
  2. {$MODE OBJFPC}
  3.  
  4. program OpenPipe;
  5.  
  6. begin
  7.   WriteLn('Standard Input Handle Value is: ', StdInputHandle);
  8. end.
  9.  

Try this in Windows with the following commands:

MyExe.exe
DIR C:\ | MyExe.exe


Did you try with GUI apps?
Title: Re: How is the pipeline transferred?
Post by: ASBzone on February 08, 2022, 04:42:15 am
Did you try with GUI apps?


Nope...
Title: Re: [Solved] How is the pipeline transferred?
Post by: jcmontherock on February 08, 2022, 10:51:11 am
What I am using:
Code: Pascal  [Select][+][-]
  1. var
  2.   StringArray: TStringArray;
  3.   Line:         AnsiString;
  4.   FileStream:   TFileStream;
  5.   rc:           Boolean;
  6. ....
  7.   StringArray := TStringArray.Create('/c', 'dir');
  8.   rc := RunCommand('cmd.exe', StringArray, Line, [poStderrToOutPut]);
  9.   if rc = False then WriteLn('Some error has been happend !...' + sLineBreak);
  10.   WriteLn('Command: ' + Line);
  11.  
  12.   Memo1.Text := Line;
  13.  
  14.   FileStream := TFileStream.Create('output.txt', fmCreate);
  15.   FileStream.Write(Line[1], Length(Line));
  16.   FileStream.Free;
  17.  
TinyPortal © 2005-2018