Recent

Author Topic: [SOLVED] Process.Terminate(0); not working  (Read 2547 times)

petevick

  • Sr. Member
  • ****
  • Posts: 388
Re: Process.Terminate(0); not working
« Reply #15 on: May 20, 2024, 01:28:18 pm »
Yes, I'm beginning to understand what's happening now. Qcad does indeed run from a launcher. I've used ps -A in terminal and qcad and qcad-bin are listed, using the PID for qcad-bin, the kill command does finally kill Qcad.
There you go  :) .

MarkMLI was a bit more focused than I was... Now the question becomes what you want to do about it and what you can do about it (depending on the purpose of your application/tprocess launcher)

I have to admit that is a bit cloudy for me as well.... e.g.  I do not know if there is an universal way to be able to always kill everything some initial process launched.
I've noticed in the ps -A output that the PID for qcad-bin has always been the PID for qcad plus 1, the qcad PID is what Process.ProcessID gives. I'm thinking that this is not reliable though, but if I change my code above to......
Code: Pascal  [Select][+][-]
  1.     fpKill(Proc.ProcessID + 1, SIGTERM);
  2.     Proc.WaitOnExit();
....then it does actually work. I think I should look to be getting the PID of qcad-bin to be safe.
Pete Vickerstaff
Linux Mint 21.2 Cinnamon, Windows 10, Lazarus 3.4, FPC 3.2.2

MarkMLl

  • Hero Member
  • *****
  • Posts: 7443
Re: Process.Terminate(0); not working
« Reply #16 on: May 20, 2024, 01:55:33 pm »
....then it does actually work. I think I should look to be getting the PID of qcad-bin to be safe.

I'd not trust that +1 relationship if I were you, sooner or later it will clash with another process being started up by systemd or whatever.

Frankly, as I've already said, I'd use killall for this. You're also likely to find that when you use that the outer wrapper will terminate automatically.

I suggest you'll find something like this useful:

Code: Text  [Select][+][-]
  1. ps faux | grep -B 5 -A 5 qcad-bin
  2.  

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

petevick

  • Sr. Member
  • ****
  • Posts: 388
Re: Process.Terminate(0); not working
« Reply #17 on: May 20, 2024, 05:27:35 pm »
After a lot of Googling and even a conversation with ChatGPT, I've finally got a rough, but working procedure, it does need a certain amount of checks adding, like empty strings etc, but I think it's a sound basis to work off. One other 'little' thing to throw in the mix, there could already be an existing Qcad process running that I have to avoid closing !!. Here's the code...........
Code: Pascal  [Select][+][-]
  1. procedure TWSplash.CloseQcadClick(Sender: TObject);
  2. {$IFDEF Linux}
  3. var
  4.   CProc: TProcess;
  5.   StrList: TStringList;
  6.   Str: String;
  7.   x: Integer = 0;
  8. {$ENDIF}
  9.   begin
  10.     {$IFDEF WINDOWS}
  11.     Form1.proc.Terminate(0);  // process created in the main form
  12.     {$ENDIF}
  13.     {$IFDEF Linux}
  14.     CProc:= TProcess.Create(nil);
  15.     StrList:= TStringList.Create;
  16.     CProc.Executable:= 'sh';
  17.     CProc.Parameters.Add('-c');
  18.     CProc.Parameters.Add('pgrep -f qcad-bin');
  19.     CProc.Options := CProc.Options + [poWaitOnExit, poUsePipes];
  20.     CProc.Execute;
  21.     StrList.LoadFromStream(CProc.Output);
  22.     x:= StrList.Count;
  23.     if x = 2 then Str:= StrList[0];
  24.     if x > 2 then Str:= StrList[1];
  25.     CProc.Free;
  26.     StrList.Free;
  27.     fpKill(StrToInt(Str), SIGTERM);
  28.     {$ENDIF}
  29.   end;
One odd thing is that with one Qcad process running, typing 'pgrep -f qcad-bin' in the terminal gives one line of output, but the TProcess output gives two lines, I can't figure out what the second PID is. With two Qcad processes I know that the one I start in Lazarus is the second line of output. but as I say, it's all a bit rough and ready and needs lots of finessing.

Many many thanks to  MarkMLI and TRon for your help and guidance. Also thanks to MarkMLI for giving me the word of the month, possibly year - fossicking  :D :D
« Last Edit: May 20, 2024, 05:33:51 pm by petevick »
Pete Vickerstaff
Linux Mint 21.2 Cinnamon, Windows 10, Lazarus 3.4, FPC 3.2.2

MarkMLl

  • Hero Member
  • *****
  • Posts: 7443
Re: Process.Terminate(0); not working
« Reply #18 on: May 20, 2024, 05:44:40 pm »
You're welcome, but I think you've got the idea that this is basically a Linux ** issue and you needed to look at how processes hung together.

Once you know the pid of your qcad-bin, process, you should be able to work backwards through (lots of handwaving here) /proc to verify that it's one of your app's children.

** I almost put unix there. However I decided not to since there's quite a lot of variation in the way that ps and /proc behave across different unices: in particular between Linux and SunOS which as a member of the BSD clan probably means that I need to be careful about giving advice that e.g. Mac users might find misleading.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

petevick

  • Sr. Member
  • ****
  • Posts: 388
Re: [SOLVED] Process.Terminate(0); not working
« Reply #19 on: May 20, 2024, 09:00:38 pm »
Just to finalise this post, I've simplified the procedure somewhat, and also got rid of the mystery PID by removing the 'sh' command. The output is now purely a list of PID's for any qcad-bin processes only, the last in the list being the one I want to terminate......
Code: Pascal  [Select][+][-]
  1. procedure TWSplash.CloseQcadClick(Sender: TObject);
  2. {$IFDEF Linux}
  3. var
  4.   CProc: TProcess;
  5.   StrList: TStringList;
  6. {$ENDIF}
  7. begin
  8.   {$IFDEF WINDOWS}
  9.   Form1.proc.Terminate(0);
  10.   {$ENDIF}
  11.   {$IFDEF Linux}
  12.   StrList:= TStringList.Create;
  13.   CProc:= TProcess.Create(nil);
  14.   try
  15.     with CProc do
  16.     begin
  17.       Executable:= 'pgrep';
  18.       Parameters.Add('-f');
  19.       Parameters.Add('qcad-bin');
  20.       Options := Options + [poWaitOnExit, poUsePipes];
  21.       Execute;
  22.       StrList.LoadFromStream(Output);
  23.     end;
  24.     if StrList.Count > 0 then
  25.       fpKill(StrToInt(StrList[StrList.Count-1]), SIGTERM)
  26.     else
  27.       CloseQcad.Visible:= False;
  28.   finally
  29.     CProc.Free;
  30.     StrList.Free;
  31.   end;
  32.   {$ENDIF}
  33. end;
Pete Vickerstaff
Linux Mint 21.2 Cinnamon, Windows 10, Lazarus 3.4, FPC 3.2.2

 

TinyPortal © 2005-2018