[fpc-pascal] TProcess vs RunProcess()

Marco van de Voort marcov at stack.nl
Sun Jan 29 22:41:28 CET 2017

In our previous episode, Santi said:
> and people nowadays love to name directories and files with strings that 
> instead of titles look like abstracts.
> In delphi and other languages I've hit may times the 260 character limit 
> in windows running  a Shell or using ShellApi (I supposed the limit was 
> 255, not 260, there are always new things to learn) , I have also hit 
> that limit using the command line. Nevertheless using windows API 
> createprocess, there is not such limit (but the call is less handy and 
> more verbose)

There is a lot of confusion about this. (only -W calls can do larger
versions, and only if \\.\, but there are also reports that it works with -A
as long as the system is capable)

> or maybe I haven't hit it because parameters and call function are
> separated strings , so they are shorter strings.  On the other hand,
> CreateProcess must call an executable file, can't execute internal
> commands like 'dir' or 'del', not a big deal but there it is.  I think
> that the limit is in the command line interpreters command.exe and
> cmd.exe.

Internal commands are not internal to the OS, but internal to the shell, so
you need to execute a shell for that. On both Linux and Windows.
> As far as I see, ExecuteProcess finally calls to an external symbol 
> named 'FPC_SYSCALLx'. And TProcess finally calls an external symbol 
> 'FPC_SYSC_FORK'. Maybe ExecuteProcess is calling some kind of shell, 
> Freepascal developers will tell.

On *nix, both will call fork followed by execve. On Windows it will call
CreateProcess, though executeprocess will call -W in trunk, and afaik
TProcess still -A.

> In my delphi days we implemented a procedure ("RunCommand" was it's 
> name, If memory serves), that was a warp to a complex call to 
> createprocess to avoid these problems. Maybe executeProcess could be 
> implemented this way. Don't know what are the drawbacks (slower, more 
> memory..?)

ExecuteProcess is to have some portable execution functionality in the base
RTL. For more complex cases there is the TProcess class that also supports
piping etc.

Some likely scenarios (e.g. run and capture stdout) have been prepared in
RunCommand, also in unit Process.

The main motivation for adding these is that 90+% of the TProcess and
CreateProcess usage in the forums was faulty (specially for larger outputs
or when the process also printed a lot on stderr (thanks Pierre!)).

Abstracting them in RunCommand reduces the amount of faulty code in play.

More information about the fpc-pascal mailing list