Recent

Author Topic: TProcces - On close console....  (Read 874 times)

mpknap

  • Full Member
  • ***
  • Posts: 155
TProcces - On close console....
« on: August 09, 2020, 10:50:09 am »


How to detect when the console window is closed? Using button1 I run a Python script. The button then takes button1.eneble = false. (I protect against restarting by the User.)

Since the script runs for a long time, the habit of several days assumes that the user will want to close the console himself. When it does, I want button1.eneable = true.

I tried it but it doesn't work:  (Windows 10)
Code: Pascal  [Select][+][-]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   RunProgram: TProcess;
  4. begin
  5.   button1.Enabled:=false;
  6.   RunProgram := TProcess.Create(nil);
  7.   RunProgram.CommandLine := 'python C:\DataCenter\PythonScript\export.py';
  8.   RunProgram.Execute;
  9.   if RunProgram.ExitStatus < 1 then button1.Enabled:=true;
  10.   RunProgram.Free;
  11.  // ShowMessage('ExitCode = '+RunProgram.ExitCode.ToString+'ExitStatus = '+RunProgram.ExitStatus.ToString);
  12.  
  13. end;      

Angus

  • New Member
  • *
  • Posts: 16
Re: TProcces - On close console....
« Reply #1 on: August 09, 2020, 12:23:26 pm »
Hello mpknap,

I also use Lazarus to launch Python scripts and pass them arguments.  I can respond to the exit code, but I have WaitOnExit set.

Code: Pascal  [Select][+][-]
  1. begin
  2.     AProcess := TAProcess.Create(nil);
  3.     try
  4.       AProcess.Executable := 'cmd.exe';
  5.       AProcess.Parameters.Add('/c');
  6.       AProcess.Parameters.Add('python');
  7.       AProcess.Parameters.Add(IniSettings.ScriptFile); //<-- path to python script
  8.       AProcess.ShowWindow := swoShowNormal;
  9.       AProcess.Execute;
  10.     finally
  11.       Aprocess.WaitOnExit; // <-- put wait on exit here
  12.       ShowMessage(IntToStr(AProcess.ExitStatus)); // <-- shows exit status returned
  13.       AProcess.Free;
  14.     end;
  15.   end;                      

This seems to work for me.

Kind regards,

Angus

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: TProcces - On close console....
« Reply #2 on: August 09, 2020, 12:45:36 pm »
(you might also have a look at the timed runcommand for FPC 3.2.0+:

https://forum.lazarus.freepascal.org/index.php/topic,50525.msg368880.html#msg368880

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: TProcces - On close console....
« Reply #3 on: August 09, 2020, 03:45:47 pm »
In your current design there are 3 options:
1. Blocking wait, with RunProgram.WaitOnExit your program blocks until the process is finished. Pros: This is the easiest solution. Contra: this freezes your window and gives the windows "XXX does not response" error.
2. ProcessMessage waiting:
Code: Pascal  [Select][+][-]
  1. while RunProgram.Running do
  2.   begin
  3.     Application.ProcessMessages;
  4.     Sleep(0);
  5.   end;
Pros: the app stays responsive and events are executed while waiting for the process. Also works single threaded Contra: The most complex solution as you need to make sure no other event can block your application because this would block this loop. Also some things like neatly killing the app in an event might get tricky. You basically have to think about a lot more stuff because you always return to that loop.

3. Async process: This class is event controlled:
Code: Pascal  [Select][+][-]
  1.   p := TAsyncProcess.Create(nil);
  2.   p.OnTerminate:=@processTerminated;
  3.   p.CommandLine := 'python C:\DataCenter\PythonScript\export.py';
  4.   p.Execute;
  5. end;
  6.  
  7. procedure TForm1.processTerminated(Sender: TObject);
  8. begin
  9.   // Process finished, do what you need to do afterwards
  10.   Sender.Free;  // Free memory afterwards so you don't leak it
  11. end;
Pro: Pretty easy and does not freeze your application. Contra: your control flow is separated by events so your code flow is separated into multiple not directly related functions

I personally would use the third option but would create the process without showing the console (can be set via options) and put a stop button into you application which can kill the process if it takes to long, so the user does not need to "close the console" and can control everything from within your application. Also this is portable, while the console closing thingy is windows only
« Last Edit: August 09, 2020, 03:49:49 pm by Warfley »

Edson

  • Hero Member
  • *****
  • Posts: 1301
Re: TProcces - On close console....
« Reply #4 on: August 10, 2020, 07:58:19 pm »
You could use https://github.com/t-edson/UnTerminal

It's a wrapper for TProcess and include events, states of connection, and prompt detection.
Lazarus 2.2.6 - FPC 3.2.2 - x86_64-win64 on Windows 10

 

TinyPortal © 2005-2018