Do you have any idea how to fix this?
First and foremost: do not access FRunner.Process directly.
It is a private property and the thread has no control over it nor does it know how to handle a graceful process termination.
As a result, every time you call Terminate you create a memory leak.
You need some changes:
1. Introduce the TerminationRequested variable and use it in the loop as I suggested earlier for TShellCommandRunner.
2. Introduce an abort method for the runner that controls this variable.
3. Introduce an abort method to the thread that you call. It calls abort method of the runner for you.
See attachment for the changes.
The one single issue that you need to resolve is to make sure the thread is not already freed when you abort it.
This can only be safely done by using a synchronization mechanism between the runner thread and the main thread (e.g. criticalsection).
But if the abort is only used at program shutdown it probably is ok (you can always put the call of the thread.abort method in a try/except block. If it fails the thread was already freed.)