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:
while RunProgram.Running do
begin
Application.ProcessMessages;
Sleep(0);
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:
p := TAsyncProcess.Create(nil);
p.OnTerminate:=@processTerminated;
p.CommandLine := 'python C:\DataCenter\PythonScript\export.py';
p.Execute;
end;
procedure TForm1.processTerminated(Sender: TObject);
begin
// Process finished, do what you need to do afterwards
Sender.Free; // Free memory afterwards so you don't leak it
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