|
FOROS PROFESIONALES WINDEV, WEBDEV y WINDEV Mobile |
| | | | | |
Reading an external program output from WinDev Application |
Iniciado por guest, 12,oct. 2010 09:23 - 11 respuestas |
| |
| | | |
|
| |
Publicado el 12,octubre 2010 - 09:23 |
Hi All: In WInDev, I need to run an external program in Command Line (for example, using ExeRun()), and read the output from this program from the WinDev application. I know it's possible to redirect to a file using the ">" operator, but for some reason it's not working, because when I call the program like "program.exe > tempfile.txt", the program.exe takes the ">" symbol as a command line option, so the shell is interpreting the ">" symbol as a command line and not as a redirection command... Anyway, I would also like to avoid using files between the external program and WInDev application, so my question is if there is a way to read the output from the external program directly from WinDev. The Output is the Standard Output defined in Windows, so we would need to capture this STDO from WinDev. Any help would be appreciated. Regards; Michael |
| |
| |
| | | |
|
| | |
| |
Publicado el 12,octubre 2010 - 12:54 |
Hi, use global shared memory zone an comunicate thru memory directly. Regards. |
| |
| |
| | | |
|
| | |
| |
Publicado el 12,octubre 2010 - 19:56 |
Hi Novica: It sounds interesting! But, how can I know the memory address for the Standard Output that the Command line is using? I have no control over this... Thanks; Michael |
| |
| |
| | | |
|
| | |
| |
Publicado el 12,octubre 2010 - 19:57 |
Hi Michael, Shouldn't it be ">>"? Georgio |
| |
| |
| | | |
|
| | |
| |
Publicado el 13,octubre 2010 - 01:09 |
Hi Giorgio: The ">>" operator is used for redirection to a file/device, but it appends the content (rather than overwrite the file). I'm trying to avoid the use of files. I'm looking the way to capture the command line output (Standard Output) from the WinDev App. May be using Pipes? Michael |
| |
| |
| | | |
|
| | |
| |
Publicado el 13,octubre 2010 - 01:11 |
Hi Michael From Windev help:
Overview WinDev, WebDev and WinDev Mobile propose to handle the shared memory zones. The shared memory zones are a communication mechanism between several applications on a given computer. They are used to easily exchange data between a service and the setting application for instance. The functions for managing the shared memory zones use the standard APIs of the different operating systems (Windows or Linux) and they facilitate the interoperability between the WinDev/WebDev/WinDev Mobile applications and the applications developed in other languages.
How do I proceed? Creating a shared memory zone The shared memory zones are created and opened by fMemOpen. The first application that accesses the zone will provoke its creation while the other applications will perform a simple opening. The application that creates the zone defines its size by supplying a minimum size. The operating system will create a zone whose size is a multiple of the size of the memory pages (4 KB sous in Windows 32 bits for example). The actual size of the memory zone is returned by fSize.
// Open the shared memory zone IdZone is int IdZone = fMemOpen("MySharedZone",50,shareGlobal) IF IdZone>0 THEN ZoneSize is int ZoneSize = fSize(IdZone) Info(StringBuild("The memory zone %1 was opened. Its size is equal to %2 bytes.",... IdZone,ZoneSize)) END ... // Close the shared memory zone fClose(IdZone) Copy this code
Finding out whether a shared memory zone already exists In some cases, it may be useful to find out whether a shared memory zone already exists. For example, an application used to configure a service can check whether the service is properly started: all you have to do is check whether a specific shared memory zone was created by the service. If the zone does not exist, an error message can be displayed by the application. fMemExist is used to find out whether a shared memory zone has already been created by another application.
// Check the existence of the shared memory zone IF fMemExist("MySharedZone",shareGlobal)=False THEN Error("Check whether the XXX server was started.") RETURN END Copy this code
Handling the content of a shared memory zone by programming To handle the content of a shared memory zone, you can: use the functions for reading and writing in the external files. This solution is recommended for the simple cases (transmission of a string for example). use the automatic serialization of WLanguage (Serialize and Deserialize), then use the functions for reading and writing in the external files to transmit the elements. This solution is recommended when transmitting classes whose members correspond to the elements to transmit. The following functions for managing the external files can be used with the shared memory zones:
fWrite Writes: a character string into an external file. a section of memory fWriteLine Writes a line into a text file (in ANSI or UNICODE format) fRead Reads: a block of bytes (characters) in an external file (ANSI or Unicode), the content of an external file (ANSI or Unicode) and assigns it to a memory zone fReadLine Reads a line in an external file (in ANSI or UNICODE format) fSeek Returns and modifies the current position in an external file
Dialog between several applications Two applications can share data by using a shared memory zone. Two synchronization mechanisms are available: the automatic notification (by using the callback functions) the manual synchronization via a semaphore.
Automatic notification of modifications The automatic notification of modifications can be implemented as soon as a shared memory zone is opened. To do so, each application that accesses the memory zone must give the name of WLanguage procedure in last parameter of fMemOpen. This procedure will be automatically called whenever the content of the shared memory zone is modified. To wait for the notification to have been processed by the other applications (before performing a new modification of the memory zone for instance), you must use fMemWait.
// Open the memory zone in the application 1 IdZone is int IdZone = fMemOpen("SharedZone",200,shareGlobal,"ModifMemory") ... -- Procedure used for callback (application 1) PROCEDURE ModifMemory(ModifZoneName is string,IdModifZone is int) Info(StringBuild("The %1 zone was modified.",ModifZoneName)) Copy this code // Open the memory zone in the application 2 IdZone is int IdZone = fMemOpen("SharedZone",200,shareGlobal,"ModifMemory") // Write into the zone fWrite(ZoneID,"Hello, I am the application 2.") // Wait for the validation of "Info" of the "ModifMemory" procedure in the application 1 fMemWait(IdZone) // Second write operation in the zone fWrite(IdZone,"New information.") ... Copy this code
Manual synchronization The manual synchronization can be performed according to the following principle: The applications open the shared memory zone and the dialog semaphore. The first application "takes" the semaphore (SemaphoreStart). The first application writes its data into the memory zone. The first application frees the semaphore (SemaphoreEnd). The second application "takes" the semaphore. The second application reads the data written by the first application. The second application frees the semaphore. Note: If the two applications want to exchange data, two semaphores must be used to insure the regulation. Tip: The manual synchronization will be preferably used when: one of the two applications is not written in WLanguage. the mechanism for notification of modifications is not available.
Naming the shared memory zones The shared memory zones are identified by their name. Note: The names of the shared memory zones are case sensitive in Windows and in Linux. Managing the share mode The share mode differs according to the versions of the operating systems: Linux, Windows 2000 and earlier: there is a single space for creating the share memory zone. The parameter of fMemOpen is ignored. Windows XP: the parameter of fMemOpen is effective if the service for quick change of user is enabled, otherwise it is ignored. Windows Vista and later: the parameter of fMemOpen is managed. The services and the users are located in a different space. To share a memory zone between a service and an application in the session of a user, the shareGlobal constant must be used. In Terminal Server: the parameter of fMemOpen is managed. Each session opened on the Terminal Server has a different memory space. The applications started in the same TSE session can share a memory zone created with the shareUser constant. The applications located in different sessions can share a shared memory zone created with the shareGlobal constant. Correspondence between the name supplied to fMemOpen and the opening in C The two following code examples present the opening of a memory zone (named "myzone") in WLanguage and in C).
// Code in WLanguage IdZone is int IdZone = fMemOpen("myzone",1024,shareGlobal) Copy this code // Equivalent code in C char * szZoneName = "myzone"; int nSize; int nMem; key_t nKey; int nAccess = 0666; // Open in read/write nSize = 1024; nKey = ftok(szZoneName+sizeof(char),(int) szZoneName[0]); nMem = shmget(nKey, nSize , nAccess); Copy this code
Related Examples : Tutorial example : WD SharingMemory [ + ] This example shows how to use the memory sharing functions introduced in WinDev 15. Several applications may share some data when they are started at the same time. In this case, you may need to share a memory zone. This memory zone will allow all the started applications to share some information. |
| |
| |
| | | |
|
| | |
| |
Publicado el 13,octubre 2010 - 09:07 |
Hi Novica: Thanks for taking the time. From the WinDev Application, there is no problem. But the other application is already done, and I don't have a way to create a Memory Zone from this side. I call this application from my WinDev App, and the results are sending to the STD Output (you can see the results in the Command Line window). This is the information I need to capture and show in the WinDev App. However, I don't know how to create a Memory Zone and redirect the messages that is being sent to the STD Output to that Memory Zone. Regards; Michael. |
| |
| |
| | | |
|
| | |
| |
Publicado el 13,octubre 2010 - 14:39 |
Michael, create a batch file (bat or cmd) with the commands and options you need. Or build it from within your wd-program. And start that bat/cmd using exerun(). You still need the > operator and a tmp-file to get the results. |
| |
| |
| | | |
|
| | |
| |
Publicado el 27,octubre 2010 - 16:06 |
Hi Michael I just stumbled on something that looks like a valid answer to your question on the french forum... Here is a translation: Use the wddos class from drCharly93 available here: http://sourceforge.net/projects/wdforge/files/Classes/WD7Dos/cl_7.5WDDos-1.0.0.zip/download It allows to get the info resulting froma DOS command without opening a dos console. example: 1 - include the wddos.cdc class in your project 2 - In global delcare a WDDos object
MyCommand is WDDos 3 - Declare a local procedure to capture the output of the command (here, by example, I display the output in an edit field called DisplayDos)
Procedure WDDOS_ReceiveOutputs(pCommandOutPut is string) DisplayDOS = DisplayDOS + pCommandOutPut 4 - Run the DOS command
DisplayDos = "" MyCommand:CommandLine_Let("ipconfig /all") MyCommand:ExecuteCommand()
---- I haven't tested, but I think it's worth a try Let us know Best regards |
| |
| |
| | | |
|
| | |
| |
Publicado el 22,diciembre 2014 - 10:11 |
I have just used this - it's a bit strangely coded, and I will make a few small changes, but it works great even with WD19.
Thanks for pointing to it.
Kind Regards
Ben |
| |
| |
| | | |
|
| | |
| |
Publicado el 21,octubre 2024 - 10:56 |
Fabrice Harari wrote:
Hi Michael I just stumbled on something that looks like a valid answer to your question on the french forum... Here is a translation: Use the wddos class from drCharly93 available here: http://sourceforge.net/projects/wdforge/files/Classes/WD7Dos/cl_7.5WDDos-1.0.0.zip/downloadIt allows to get the info resulting froma DOS command without opening a dos console. example: 1 - include the wddos.cdc class in your project 2 - In global delcare a WDDos object MyCommand is WDDos 3 - Declare a local procedure to capture the output of the command (here, by example, I display the output in an edit field called DisplayDos) Procedure WDDOS_ReceiveOutputs(pCommandOutPut is string) DisplayDOS = DisplayDOS + pCommandOutPut 4 - Run the DOS command DisplayDos = "" MyCommand:CommandLine_Let("ipconfig /all") MyCommand:ExecuteCommand() ---- I haven't tested, but I think it's worth a try Let us know Best regards
This wddos program works. But in 64 bit environment it didnt work. |
| |
| |
| | | |
|
| | |
| |
Publicado el 07,junio 2025 - 13:03 |
a écrit :
Fabrice Harari wrote: Hi Michael I just stumbled on something that looks like a valid answer to your question on the french forum... Here is a translation: Use the wddos class from drCharly93 available here: http://sourceforge.net/projects/wdforge/files/Classes/WD7Dos/cl_7.5WDDos-1.0.0.zip/downloadIt allows to get the info resulting froma DOS command without opening a dos console. example: 1 - include the wddos.cdc class in your project 2 - In global delcare a WDDos object MyCommand is WDDos 3 - Declare a local procedure to capture the output of the command (here, by example, I display the output in an edit field called DisplayDos) Procedure WDDOS_ReceiveOutputs(pCommandOutPut is string) DisplayDOS = DisplayDOS + pCommandOutPut 4 - Run the DOS command DisplayDos = "" MyCommand:CommandLine_Let("ipconfig /all") MyCommand:ExecuteCommand() ---- I haven't tested, but I think it's worth a try Let us know Best regards This wddos program works. But in 64 bit environment it didnt work.
ce code fonctionne bien avec windev 25 merci |
| |
| |
| | | |
|
| | | | |
| | |
| | |
| |
|
|
|