dummzeuch 1506 Posted June 13, 2019 I have got two programs, both written in Delphi using the VCL. Program1 excecutes Program2 using CreateProcess, passing some parameters. In some circumstances I would like Program2 to return a string to Program1. Since CreateProcess only returns an exit code, which is a number, this requires some additional communication. Converting program2 into a DLL or Package is not an option in this case, neither is integrating the source code of program2 to program1. The simplest way would probably be that program1 passes a file name to program2, program2 creates that file, writes the string to it and exits. It could of course be implemented much more complicated, e.g. via sockets, Windows Messages, Shared Memory or even WriteProcessMemory. Have you done something like this? If yes, which method did you use and what was your experience? Share this post Link to post
Uwe Raabe 2059 Posted June 13, 2019 Named Pipes may not be the badest decision here. See François Piette blogging about that: Inter Process Communication Using Pipes 1 Share this post Link to post
Микола Петрівський 10 Posted June 13, 2019 Just create global atom and pass it's code to the caller. Or caller can create empty atom, and then check for changes. Share this post Link to post
David Heffernan 2347 Posted June 13, 2019 Reading the stdout of the child process is a very easy way to do this. 3 1 Share this post Link to post
dummzeuch 1506 Posted June 13, 2019 1 hour ago, Микола Петрівський said: Just create global atom and pass it's code to the caller. Or caller can create empty atom, and then check for changes. From the description it looks to me that atoms are immutable. So how do you propose to return a string from program2 to program1 via a global atom? Share this post Link to post
Lars Fosdal 1792 Posted June 13, 2019 What about a memory mapped file? An idealist kind of solution could perhaps be a message queue system like f.x. RabbitMQ (https://www.rabbitmq.com/) Share this post Link to post
dummzeuch 1506 Posted June 13, 2019 I would like to remind you that I was asking for experience with the IPC methods: 3 hours ago, dummzeuch said: Have you done something like this? If yes, which method did you use and what was your experience? For now I have implemented it with passing a file name as described in my original post. Does this have any drawbacks (apart from the obvisous one: It creates a race condition. I have mitigated this for now by creating a unique temporary directory to place the file in. Share this post Link to post
limelect 48 Posted June 13, 2019 I used on D6 ,many years ago , mdMailSlot https://torry.net/authorsmore.php?id=152 It communicated between 4 computers (programs) maid with Delphi 6. Excellent 1 Share this post Link to post
PeterBelow 238 Posted June 13, 2019 4 hours ago, dummzeuch said: I have got two programs, both written in Delphi using the VCL. Program1 excecutes Program2 using CreateProcess, passing some parameters. In some circumstances I would like Program2 to return a string to Program1. Since CreateProcess only returns an exit code, which is a number, this requires some additional communication. Converting program2 into a DLL or Package is not an option in this case, neither is integrating the source code of program2 to program1. The simplest way would probably be that program1 passes a file name to program2, program2 creates that file, writes the string to it and exits. It could of course be implemented much more complicated, e.g. via sockets, Windows Messages, Shared Memory or even WriteProcessMemory. Have you done something like this? If yes, which method did you use and what was your experience? A fairly simple method is to pass a window handle to program2 on the command line an then have that program sent its result back in a WM_COPYDATA message to that window. Only caveat: program1 must not wait on program2 to finish in a manner that blocks message processing of the main thread. 2 Share this post Link to post
FredS 138 Posted June 13, 2019 1 hour ago, dummzeuch said: It creates a race condition I don't understand the 'race condition'? I mean you are doing the most basic of all communications, execute an app, wait for it to exit and read the output file. In one form or another we do this every day 🙂 But since you are fishing for experience, I use this as part of a self updating feature. Get a Temp filename from the OS Write some data to it Execute another app waiting for it to complete Read any Error code it may have added to the file Delete the file Other than the New feature where a user can add the Temp folder to the 'Controlled Folder Access' Ransomware Protection this is as basic as it gets. Share this post Link to post
dummzeuch 1506 Posted June 13, 2019 19 minutes ago, FredS said: I don't understand the 'race condition'? If there are multiple instances of program1 and it always uses the same file name when it starts its own instance of program2. These multiple instances would then all write to the same file. That's a race condition in my opinion. Share this post Link to post
FredS 138 Posted June 13, 2019 1 minute ago, dummzeuch said: always uses the same file name OK, getting a temp filename from the OS solves that. Share this post Link to post
Lars Fosdal 1792 Posted June 14, 2019 19 hours ago, dummzeuch said: If there are multiple instances of program1 and it always uses the same file name when it starts its own instance of program2. These multiple instances would then all write to the same file. That's a race condition in my opinion. I'd call that a concurrency issue, rather than a race condition? SharedFileName := '%temp%\MyFileName.ext.' + GetCurrentProcessId.ToString; Share this post Link to post
David Heffernan 2347 Posted June 14, 2019 This is the dictionary definition of a race 1 Share this post Link to post
Lars Fosdal 1792 Posted June 16, 2019 Depends on the dictionary, I guess. Race conditions rarely flag as errors, but cause inconsistent or erratic data, possibly leading to wrongful processing later on. In this case, at least one of the four parties would be denied access (due to exclusive write lock and - depending on the programmmer - exclusive read) to the file and hence should have/raise awareness of a problem. But, whatever. Share this post Link to post
David Heffernan 2347 Posted June 16, 2019 1 hour ago, Lars Fosdal said: Depends on the dictionary, I guess. Race conditions rarely flag as errors, but cause inconsistent or erratic data, possibly leading to wrongful processing later on. In this case, at least one of the four parties would be denied access (due to exclusive write lock and - depending on the programmmer - exclusive read) to the file and hence should have/raise awareness of a problem. But, whatever. Well, there are plenty of types for which races lead to errors. But how races manifest is not part of what defines them. A race is simply unserialised access to a shared resource. There aren't multiple definitions of this term. Share this post Link to post
LCAO-MO 0 Posted July 27, 2019 Dear Dummzeuch, Try Add-in A-Tools: Query, Share Excel file on LAN, internet with multiple users. See more details at http://www.atoolspro.com/ You can download at http://bluesofts.net/Download/phan-mem/phan-mem-mien-phi.html Try it and find out how it works, as it describes you looking for a solution to your need solve? It's in-process-server (file AddinATools.dll), programmed in delphi language. Best Regards! Share this post Link to post
dummzeuch 1506 Posted July 27, 2019 2 hours ago, LCAO-MO said: It's in-process-server (file AddinATools.dll), programmed in delphi language. Thanks for the suggestion, but that sounds like quite some overkill for my purpose. Share this post Link to post
timfrost 78 Posted July 27, 2019 To answer your question, yes, I have done exactly this. But in my case program 1 was guaranteed to be a singleton on the machine, so I could just create an empty registry key before invoking program 2 and have program 2 place the result there. If you have control over the number of instances of your program 1 you might be able to adapt this solution. It has the advantages of extreme simplicity and needing no extra tools or special functions. 1 Share this post Link to post
Fr0sT.Brutal 900 Posted August 8, 2019 Why inventing bicycles with triangular wheels when writing to STDOUT is a very simple method proven by decades? All *nix ecosystem is built on this mechanism. Executed app won't need anything more than WriteLn and executor app will have to intercept pipe handles. 1 1 Share this post Link to post
Joseph MItzen 251 Posted August 16, 2019 On 8/8/2019 at 3:59 AM, Fr0sT.Brutal said: Why inventing bicycles with triangular wheels when writing to STDOUT is a very simple method proven by decades? All *nix ecosystem is built on this mechanism. Executed app won't need anything more than WriteLn and executor app will have to intercept pipe handles. Thank you; I'm reading this on a Linux box and thought I was missing something for a second. "Write programs to handle text streams, because that is a universal interface." - Peter H. Salus, "A Quarter-Century of Unix" Now, the question is how to handle this with Delphi... Delphi has never gained a simple solution for calling programs and getting the text results back, which is a weird and glaring omission in my mind. FreePascal has a handful of routines for doing so (some of which work across platforms), Qt has QProcess, etc. There's some information here on FreePascal's TProcess: https://wiki.freepascal.org/TProcess and there's a port of TProcess to Delphi (which I haven't tried): https://github.com/z505/TProcess-Delphi Otherwise, you're left with the somewhat complicated default Delphi way of doing this.... https://stackoverflow.com/questions/9119999/getting-output-from-a-shell-dos-app-into-a-delphi-app 1 Share this post Link to post
David Heffernan 2347 Posted August 16, 2019 https://stackoverflow.com/q/19054789/505088 https://stackoverflow.com/q/19054789/505088 Share this post Link to post
Edwin Yip 154 Posted August 17, 2019 (edited) If you use mORMot's 'remote procedure call' or 'remote interface call' it'll be simple - in program1 create a server (without any database stuff) and expose the service via named pipe or WM_CopyData windows message. Example: https://github.com/synopse/mORMot/tree/master/SQLite3/Samples/03 - NamedPipe Client-Server Edited August 17, 2019 by edwinyzh Share this post Link to post
John Kouraklis 94 Posted August 17, 2019 Wouldn't App Tethering work in this case? Share this post Link to post
PeterPanettone 158 Posted August 18, 2019 (edited) On 6/13/2019 at 12:02 PM, dummzeuch said: Windows Messages Windows Messages is not complicated: Pass the window handle of Program1 as a parameter to Program2 which then sends the string back to Program1 as a Windows Message. Or - if Program2 is a console type program: Simply (programmatically) read the console output of Program2. Edited August 18, 2019 by PeterPanettone Share this post Link to post