Jump to content
Giorgi Chapidze

Set pipeline between UI and cmd.exe

Recommended Posts

Hi!   

I am developing a simple editor application in which you can type Pascal code and click the compile button, which will connect cmd.exe in the background and compile a .pas file via freepascalcompiler.

 

I have two separate TMemo components. one for writing source code and a second read-only component for showing compilation messages.

 

To sum up, I want to execute the "fpc file_name. pas" command in the background and then grab the compiled messages and display them on the UI.

 

How can I achieve such behavior?

https://github.com/gchapidze/fmx-pascalIDE

 

Share this post


Link to post

There is plenty of examples on how to do this with Delphi, you already got the correct term: It's (inter-process) communication (IPC) via "pipes".

 

I'd recommend to start a bit more humble by making a small console app by yourself that will, for example, take two numbers from the input, and return the sum of these two numbers. Then, try sending these two numbers to your console app and getting the result back. If that works, you can do that with your free pascal compiler.

 

By the way: Cmd.exe is nothing more than a front-end that just does what your application wants to do. You don't need to "connect" to a cmd.exe. You will directly launch and communicate with your free pascal compiler.

  • Thanks 1

Share this post


Link to post
1 hour ago, Der schöne Günther said:

There is plenty of examples on how to do this with Delphi, you already got the correct term: It's (inter-process) communication (IPC) via "pipes".

 

I'd recommend to start a bit more humble by making a small console app by yourself that will, for example, take two numbers from the input, and return the sum of these two numbers. Then, try sending these two numbers to your console app and getting the result back. If that works, you can do that with your free pascal compiler.

 

By the way: Cmd.exe is nothing more than a front-end that just does what your application wants to do. You don't need to "connect" to a cmd.exe. You will directly launch and communicate with your free pascal compiler.

Thanks for repsonse!   Frankly, I was not able to find examples on this topic, maybe because I am new to Delphi and using the wrong terms. Is linking a different thing? Anyways, if you have time, can you send me material on that?

Share this post


Link to post

A ready to use solution (which I have never tried) is 

TurboPack/DOSCommand: This component let you execute a dos program (exe, com or batch file) and catch the ouput in order to put it in a memo or in a listbox. (github.com)

 

It is said to be available throught "GetIt" as well.

 

For myself, I did it as also suggested by this fine gentleman here

On 6/28/2021 at 5:34 PM, Remy Lebeau said:

If you don't want to rely on 3rd party wrappers, it is not very overly complicated to redirect the output and read it manually.  Just create a pipe, assign it to the STARTUPINFO passed to CreateProcess(), and then read from the pipe.  MSDN documents this task:

 

Creating a Child Process with Redirected Input and Output

For the processes I spawn myself (via CreateProcess()), I just create two pipes and then use WriteFile(..) and ReadFile(..) on them. It is important that CreateProcess(..) has its "inherit handles" parameter to true.

 

If you're stuck, I might post my solution, but it contains a a lot of noise as well (such as moving the created process to a "job object" to allow easier resource scheduling or termination)

Edited by Der schöne Günther
  • Thanks 1

Share this post


Link to post

I have read the relevant part of the DOSCommand source code, and I was able to complete the project. The DOSCommand library is fairly simple and straightforward. 

 

Anyway, I will challenge myself and try to accomplish it without a third-party library.

 

@Der schöne Günther Thanks!  I will let you know!

  • Like 1

Share this post


Link to post
4 hours ago, Der schöne Günther said:

It is important that CreateProcess(..) has its "inherit handles" parameter to true.

It is equally important to make sure that only the remote ends of the pipe are actually inherited, not the local ends, or else you won't be able to handle the pipes being closed correctly when the child process exits.

 

And also, be careful if you call CreateProcess() multiple times with bInheritHandles=TRUE, as each child process may end up inheriting handles you didn't intend for it to inherit.  Vista addressed that issue with the PROC_THREAD_ATTRIBUTE_LIST option of STARTUPINFOEX:

 

Programmatically controlling which handles are inherited by new processes in Win32

Another way to create a process with attributes, maybe worse maybe better

 

  • Thanks 1

Share this post


Link to post

Many thanks, that ist most helpful. I'll give it a read.

 

I remember a system completely hanging up because one process had hundred thousands of handles it didn't close properly, then spawning a child process and trying to inherit all handles to it.

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×