The following class allows to run a set of MSDOS commands and get back a response as a string. The MSDOS window is present but not visible.
This is how the class can be tested from the VFP Command Window:
If CreateMsdosSession method returns True, then RunCommand method can be used to launch msdos commands. An output of the command processor is collected in a buffer. GetResponse method returns the content and clears the buffer.
Use this program code to test the class:
LOCAL cmd As msdos, cResponse
cmd = CREATEOBJECT("msdos")
IF NOT cmd.createmsdossession()
? "CreateMsdosSession call failed."
= INKEY(2) && gives MSDOS some time to return
cResponse = cmd.getresponse()
STORE cResponse TO _cliptext && for reviewing later
SET MEMOWIDTH TO 120
The INKEY() is here to provide some time for the command processor to generate an output. The WaitForSingleObject API, which could be an ideal solution, does not wait for a console output. May be the Timer object can do better than the INKEY() does.
The VFP class starts the command processor (cmd.exe) as a child process using the CreateProcess. Through input parameters for this call the standard input and output handles of the child process are redirected to two anonymous pipes.
The msdos window is put in a hidden state by placing STARTF_USESHOWWINDOW in STARTUPINFO structure. So the usual black msdos window does not blink and does not appear in the Task Bar.
Though it has an unexpected effect:
The code line above will start myprog.exe and place it in a hidden state. Only after the cmd object is released, the myprog.exe becomes visible and appears in the Task Bar.
* * *
Through one pipe the command processor receives commands (RunCommand method). The other pipe is used to get an output generated by the command processor (GetResponse method).
An anonymous pipe is an unnamed, one-way pipe that typically transfers data between a parent process and a child process.
This is like a temporary file that is shared by two processes. One of these processes can write to the pipe, and the other one can read from the pipe, which is what "one-way" means.
Does not return output when tested under W2K 5.00.2195
John Clarke | 2007-12-18 20:06:32
I'm not sure how to terminate grand-child process. If CMD.EXE (child) launches an application (grand-child) that takes a long time to run, I'd like to be able to handle a timeout on that process. I wonder if there is a way to retrieve the process handle for the app that we send in WriteToPipe(cCommand...). If so, we could use the WaitForSingleObject() API to trap for timeouts.