You are not logged in.
Pages: 1
The RunRedirect works very well for calling simple external commands, but it is also too simplistic.
In Python, there is a subprocess module that allows interaction with third-party processes via stdin/stdout — executing commands and retrieving their output.
This enables communication with programs like Python, Node.js, and others (I know there are solutions like Python4Delphi or SyNode, SpiderMonkey, but that's a different matter).
Maybe some JS engine like Chakaracore or QuickJS is more suitable for run js code , but the NodeJS module(ecosystem) is not something a pure engine can have.
the stdin/stdout pipe solution makes the program highly flexible and extensible (which is very important).
After a whole night of tracking and research, I found that we can easily implement this by making a few small modifications to our RunRedirect:
in RunCommandWin()
var
in_Rd,in_Wr:THandle;
...
//create a input pipe right after the output pipe
CreatePipe(In_rd, In_wr, @security, 0);
SetHandleInformation(In_wr, HANDLE_FLAG_INHERIT, 0);
//bind with process startupinfo
startupinfo.hStdInput := In_rd;//GetStdHandle(STD_INPUT_HANDLE);
//write to stdInput after CreateProcessW sucess
const jsCode:RawUtf8='2+3'
FileWriteAll(In_wr,Pointer(jsCode),length(jsCode));
if Assigned(onoutput) then
onoutput('', processinfo.dwProcessId);
//close In_wr
if rd <> 0 then
begin
// wait and redirect - see https://stackoverflow.com/a/25725197/458259
CloseHandle(In_wr);
CloseHandle(wr);
....this work sucess with nodejs.exe -i.
but i dont know how to do ,without break the mormot.core.os codebase, or make it crossplatform(maybe with Popen).
maybe we need a func like
function RunRedirect(const cmd: TFileName; Input:RawUtf8; exitcode: PInteger;
const onoutput: TOnRedirect; waitfordelayms: cardinal; setresult: boolean;
const env, wrkdir: TFileName; options: TRunOptions): RawByteString; Or even better: create a process using stdInput/stdOutput pipes, and allow external access to the process's stdInput and stdOutput handles.
eg:create process(or 10x process) with pipes then interact with it(them) at any time
This would enable more flexible interaction.
Last edited by keinn (2025-06-25 21:36:23)
Offline
Re: RunRedirect feature request (stdin)
Adding another strong use-case for roKeepStdinPipe (or similar): graceful per-process stop of multiple FFmpeg instances.
We run N FFmpeg capture processes (one per deck, up to 8) via RunRedirect. When the operator stops one deck, we need to send q\n to that specific FFmpeg — the standard graceful shutdown signal. FFmpeg then flushes its buffers, closes the output file cleanly, and exits with code 0.
The current workaround — returning true from TOnRedirect — triggers GenerateConsoleCtrlEvent(CTRL_C_EVENT, 0), which sends the signal to the entire console group. With 8 active FFmpeg processes this would kill all of them simultaneously. So we currently rely on TerminateProcess (hard kill after 5s), which risks incomplete/corrupted output files.
A roKeepStdinPipe flag that keeps the stdin write-handle accessible would allow writing q\n to the specific process and solve this cleanly. Alternatively, a roNewProcessGroup flag (CREATE_NEW_PROCESS_GROUP) would allow targeted GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid).
Either approach would make RunRedirect suitable for production multi-process management.
---
Offline
Pages: 1