Recent

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

loaded

  • Hero Member
  • *****
  • Posts: 825
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?
Check out  loaded on Strava
https://www.strava.com/athletes/109391137

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2050
  • 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 xm by KodeZwerg »

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2050
  • 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 xm by KodeZwerg »

laguna

  • Sr. Member
  • ****
  • Posts: 323
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: 825
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.
Check out  loaded on Strava
https://www.strava.com/athletes/109391137

KodeZwerg

  • Hero Member
  • *****
  • Posts: 2050
  • 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 xm by KodeZwerg »

loaded

  • Hero Member
  • *****
  • Posts: 825
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.
Check out  loaded on Strava
https://www.strava.com/athletes/109391137

 

TinyPortal © 2005-2018