Forum > General

How to make RunCommand NOT wait on exection

(1/2) > >>

zxandris:
Hey I'm trying to run an external program, with parameters but I don't actually want it to wait on execution.  I've tried quite a few things and currently have :-


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---RunCommand(exeFile, cline, GOutP, [poNoConsole], swoShowNormal);
This just waits for execution is there a way to stop it doing that please?

cJ

n7800:
There is a great article on the wiki that answers all the questions about calling an external program:

https://wiki.freepascal.org/Executing_External_Programs

marcov:
Runcommand was written to encapsulate the TProcess scenario where you want to wait.

If not, then you will have to use TProcess directly.

You need to have some check on process end, since the TProcess instance needs to be freed.

If you just want to fire and forget, on Windows try shellexecute. On Unix I don't know because afaik there it is the job of the called EXE to cut the cord rather than the one calling it.

AlanTheBeast:

--- Quote from: zxandris on March 07, 2025, 11:39:34 pm ---Hey I'm trying to run an external program, with parameters but I don't actually want it to wait on execution.  I've tried quite a few things and currently have :-


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---RunCommand(exeFile, cline, GOutP, [poNoConsole], swoShowNormal);
This just waits for execution is there a way to stop it doing that please?


--- End quote ---

I do such via threads.  Using flags or status to tell the invoking procedure (or another) to determine if the command has completed.

The other thread can signal completion in various ways.  I like to use the pointer passed to the thread to point at a boolean or state value (care to make sure the stack hasn't released, or messily with a global as below).

Here is a hastily written and tested program (that works on a mac in Terminal) where the command is running in a thread detached from the main thread:
(You'll need to complete the wrapper - I added this to an existing program - don't forget to add cthreads and classes to the uses clause).
Adjust the command for whatever OS you're on, (and the RunCommand details).

So for your purpose the "de-coupling" occurs on the BeginThread call.  How you "rendez-vous" for the result is entirely up to your imagination.

You can also use a call to BeginThread, get the ThreadID and then have a different proc or function WaitForThreadTerminate (TID).


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---VAR        SexIsFunTerminated: boolean;        SexIsFunString: ansistring;        Function SexIsFun (p:pointer):ptrint;VAR        Q : ansistring;        Result: ansistring;BEGIN        Q := ansistring(p^);   // get the command from the invoker         RunCommand ('/bin/sh',['-c',Q],Result);                ansistring(p^) := Result;  //replace the command with the result (yes: clumsy - but you can figure out better ways        SexIsFunTerminated := true;                        exit(0);END; Procedure IssueFreedCommand;BEGIN        SexIsFunTerminated := false;        SexIsFunString := 'ls -al';                      //the command to be passed with the RunCommand function (this is Unix / Linux compatible)*        BeginThread (@SexIsFun, @SexIsFunString);END; Procedure SexConnection;VAR        T: ansistring;BEGIN        // do something useful, then        While NOT SexIsFunTerminated do sleep (100);        Writeln (SexIsFunString);END; Procedure Sex;BEGIN        IssueFreedCommand;        SexConnection;END;
* I believe there is a Windows extension (?) of sorts that gives windows' terminal "Unix like" commands - but not sure

AlanTheBeast:

--- Quote from: marcov on March 08, 2025, 11:38:57 am ---If you just want to fire and forget, on Windows try shellexecute. On Unix I don't know because afaik there it is the job of the called EXE to cut the cord rather than the one calling it.

--- End quote ---

On Unix (or Mac anyway) you can "fire and forget" by making the command string something like:

   CMD : ansistring = '/Users/Bob/Applications/keepawkeawake3 & disown';
...
...
        Result := RunCommand ('/bin/zsh',['-c',CMD],S);


This creates a separate system owned thread, no terminal window is opened for it.

But that isn't what the OP wants (I believe).

Navigation

[0] Message Index

[#] Next page

Go to full version