Giorgi Chapidze 2 Posted April 14, 2023 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
Der schöne Günther 316 Posted April 14, 2023 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. 1 Share this post Link to post
Giorgi Chapidze 2 Posted April 14, 2023 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
Der schöne Günther 316 Posted April 14, 2023 (edited) 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 April 14, 2023 by Der schöne Günther 1 Share this post Link to post
Zoran Bonuš 12 Posted April 14, 2023 For a similar task I use this solution (the updated version), works fine by me: https://stackoverflow.com/questions/9119999/getting-output-from-a-shell-dos-app-into-a-delphi-app 1 Share this post Link to post
Giorgi Chapidze 2 Posted April 14, 2023 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! 1 Share this post Link to post
Remy Lebeau 1396 Posted April 14, 2023 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 1 Share this post Link to post
Der schöne Günther 316 Posted April 17, 2023 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
Zoran Bonuš 12 Posted April 24, 2023 Just for a reference, a recent blog post on the topic and a shared library by @Darian Miller https://www.ideasawakened.com/post/use-createprocess-and-capture-the-output-in-windows 1 Share this post Link to post