Recent

Author Topic: How to capture external dos commands of external applications?  (Read 435 times)

loaded

  • Hero Member
  • *****
  • Posts: 757
Hi All,
I can see the dos commands or applications run by an external application in Process Explorer. Views are attached below.
I want to keep records of what commands and applications a particular application is running.
Is there a simple way to do this? Or should I continue to use Process Explorer?
If Ide=Lazarus 2.2.4 32 Bit and Os=Win 10 Home 64 Bit 22H2 then Get up and do something useful! Because God is the helper of those who start again;

KodeZwerg

  • Hero Member
  • *****
  • Posts: 1399
  • Fifty shades of code.
    • Delphi & FreePascal
Re: How to capture external dos commands of external applications?
« Reply #1 on: March 29, 2023, 10:20:49 am »
About the used command line I can not tell much since I never investigated that deep but for your treeview on your app to show what other processes your app has started I would call the NtQueryInformationProcess method and use "InheritedFromUniqueProcessId" from the build output record to compare that PID against your apps PID to know that it belongs to that process.
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 1399
  • Fifty shades of code.
    • Delphi & FreePascal
Re: How to capture external dos commands of external applications?
« Reply #2 on: March 29, 2023, 10:35:54 am »
I guess I explained it a little wrong, with the NtQueryInformationProcess you get a back an array of record of all processes with further information like InheritedFromUniqueProcessId (what represent the owner/parent)

So you need first to build that record and afterwards parse it to sort what PID belong to whom.
I hope that was more clear.
« Last Edit: March 29, 2023, 10:37:26 am by KodeZwerg »
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

laguna

  • Sr. Member
  • ****
  • Posts: 322
Re: How to capture external dos commands of external applications?
« Reply #3 on: March 29, 2023, 11:43:09 am »
with this code output dos is show in memo in realtime

Code: Pascal  [Select][+][-]
  1.  
  2. //...
  3.   public
  4.          procedure ProcessEvent(Sender,Context : TObject;Status:TRunCommandEventCode;const Message:string);
  5.  
  6.   end;
  7.  
  8.   TProcessToMemo = class(TProcess)
  9.                              public
  10.                              fmemo : Tmemo;
  11.                              bytesprocessed : integer;
  12.                              fstringsadded : integer;
  13.                              function ReadInputStream(p:TInputPipeStream;var BytesRead:integer;var DataLength:integer;var Data:string;MaxLoops:integer=10):boolean;override;
  14.                            end;
  15.  
  16.  
  17.  
  18.  
  19. var
  20. Form1: TForm1;
  21.  
  22.  
  23.  
  24. implementation
  25.  
  26. {$R *.lfm}
  27.  
  28. { TForm1 }
  29.  
  30.  
  31.    function RunCommandMemo(const exename:TProcessString;const commands:array of TProcessString;out outputstring:string; Options : TProcessOptions = [];SWOptions:TShowWindowOptions=swoNone;memo:TMemo=nil;runrefresh : TOnRunCommandEvent=nil ):boolean;
  32.     Var
  33.         p : TProcessToMemo;
  34.         i,
  35.         exitstatus : integer;
  36.         ErrorString : String;
  37.     begin
  38.       p:=TProcessToMemo.create(nil);
  39.       if Options<>[] then
  40.         P.Options:=Options - [poRunSuspended,poWaitOnExit];
  41.       p.options:=p.options+[poRunIdle, poNoConsole];
  42.  
  43.       P.ShowWindow:=SwOptions;
  44.       p.Executable:=exename;
  45.       if high(commands)>=0 then
  46.        for i:=low(commands) to high(commands) do
  47.          p.Parameters.add(commands[i]);
  48.       p.fmemo:=memo;
  49.       p.OnRunCommandEvent:=runrefresh;
  50.       try
  51.         result:=p.RunCommandLoop(outputstring,errorstring,exitstatus)=0;
  52.       finally
  53.         p.free;
  54.       end;
  55.       if exitstatus<>0 then result:=false;
  56.     end;
  57.  
  58.    procedure TForm1.ProcessEvent(Sender, Context: TObject;
  59.       Status: TRunCommandEventCode; const Message: string);
  60.     begin
  61.       if status in [RunCommandIdle, RunCommandFinished] then
  62.         begin
  63.           if status =RunCommandFinished then
  64.             begin
  65.               memo1.lines.add(' process finished');
  66.             end;
  67.           if tprocesstomemo(sender).fstringsadded>0 then
  68.            begin
  69.              tprocesstomemo(sender).fstringsadded:=0;
  70.     //         memo1.lines.add('Handle:'+inttostr(tprocesstomemo(sender).ProcessHandle));
  71.              memo1.refresh;
  72.            end;
  73.           sleep(10);
  74.           application.ProcessMessages;
  75.         end;
  76.     end;
  77.  
  78.     { TProcessToMemo }
  79.  
  80.  
  81.     function TProcessToMemo.ReadInputStream(p:TInputPipeStream;var BytesRead:integer;var DataLength:integer;var Data:string;MaxLoops:integer=10):boolean;
  82.     var lfpos : integer;
  83.         crcorrectedpos:integer;
  84.         stradded : integer;
  85.         newstr : string;
  86.     begin
  87.       Result:=inherited ReadInputStream(p, BytesRead, DataLength, data, MaxLoops);
  88.       if (result) and (bytesread>bytesprocessed)then
  89.         begin
  90.           stradded:=0;
  91.           lfpos:=pos(#10,data,bytesprocessed+1);
  92.           while (lfpos<>0) and (lfpos<=bytesread) do
  93.             begin
  94.               crcorrectedpos:=lfpos;
  95.               if (crcorrectedpos>0) and (data[crcorrectedpos-1]=#13) then
  96.                  dec(crcorrectedpos);
  97.               newstr:=copy(data,bytesprocessed+1,crcorrectedpos-bytesprocessed-1);
  98.               fmemo.lines.add(newstr);
  99.                inc(stradded);
  100.               bytesprocessed:=lfpos;
  101.               lfpos:=pos(#10,data,bytesprocessed+1);
  102.             end;
  103.           inc(fstringsadded,stradded); // check idle event.
  104.         end;
  105.     end;
  106.  
  107. begin
  108.   RunCommandMemo('python.exe',['fec.py',username.Text,CodicePin.Text,Password.Text,Piva.Text, DateToStr(DataDal.date,fmt) , DateToStr(DataDal.date,fmt) , Serv],s,[],swonone,memo1,@ProcessEvent);
  109. end.
  110.  
  111.  

loaded

  • Hero Member
  • *****
  • Posts: 757
Re: How to capture external dos commands of external applications?
« Reply #4 on: March 29, 2023, 01:54:30 pm »
Thank you all so much for taking your precious time to reply.
KodeZwerg;
In the picture above, the cmd process is waiting for confirmation from the user to terminate it permanently. However, some commands can run and terminate very quickly without waiting for confirmation. I need to catch them too. So it seems to me that I need to somehow capture a message from the operating system. It would be worth the effort if it could be done in a simple way, but I don't need to go too deep right now.
laguna ;
I think I was misunderstood, I don't have a need for routing commands to the pipe. Consider that the application in the picture does not belong to me. I wanted to know what commands (not just dos) an external application is running after this application is running.
If Ide=Lazarus 2.2.4 32 Bit and Os=Win 10 Home 64 Bit 22H2 then Get up and do something useful! Because God is the helper of those who start again;

KodeZwerg

  • Hero Member
  • *****
  • Posts: 1399
  • Fifty shades of code.
    • Delphi & FreePascal
Re: How to capture external dos commands of external applications?
« Reply #5 on: March 29, 2023, 03:04:28 pm »
If you just need such for your own application, TProcess would be a good choice by using the poWaitOnExit option to inform your app when the process has finished (closed/terminated).
Anyway, that approach does not cover if the launched process open more.
CreateToolhelp32Snapshot/TProcessEntry32 or NtQueryInformationProcess are the things to be used to really cover everything.
« Last Edit: Tomorrow at 31:76:97 by KodeZwerg »

loaded

  • Hero Member
  • *****
  • Posts: 757
Re: How to capture external dos commands of external applications?
« Reply #6 on: March 29, 2023, 03:08:55 pm »
CreateToolhelp32Snapshot/TProcessEntry32 or NtQueryInformationProcess are the things to be used to really cover everything.

Thanks for the info, I'll look into them as soon as possible.
If Ide=Lazarus 2.2.4 32 Bit and Os=Win 10 Home 64 Bit 22H2 then Get up and do something useful! Because God is the helper of those who start again;

 

TinyPortal © 2005-2018