PDA

View Full Version : QProcess, problem getting interactive outputs



enricong
19th July 2011, 20:50
I am trying to use QProcess to interact with a command line application to retrieve data.

The application works something like this:



> execute_application

1. open database
2. close database
3. read record
4. exit

Choose Option: 1
Enter file name: blah.dat

1. open database
2. close database
3. read record
4. exit

Choose Option: 3
Enter ID#: 2365

Record: 2365
data1 ####
data2 ####
data3 ####
data4 ####


1. open database
2. close database
3. read record
4. exit

Choose Option: 4

>


My code goes something like this


QString line= "", command = "command";
QProcess *proc = new QProcess(this);
proc->start(command);
proc->waitForStarted();
proc->write("1\n");
while(!line.contains("Select function")) line = tade->readAll();
proc->write("blah.dat\n");
while(!line.contains("Select function")) line = tade->readAll();
proc->write("3\n");

...


I seem to get in consistent results. Sometimes the variable line is always empty, sometimes it contains a string but it is from two commands ago, sometimes it only contains part of the menu and the rest of the menu appears in the next read call. I have tried using "waitForBytesWritten() and waitForReadReady()" but both always seem to return immediately eventhough some of options can take up to 10 seconds to return. Sometimes adding a wait... will cause one command to return properly while it has to be removed for the next command for it to work.

Some of this seems like it could be a buffering issue so I tried the unbuffered option but this seemed to make no difference. I also tried to increase the timeout on the wait.... functions but that seemed to make no difference.

I'd like to do the following:
1. start program
2. send command
3. wait for output (next input prompt)
4. save output
5. repeat 2-4

Santosh Reddy
19th July 2011, 22:19
I think there only one way to solve your problem, konwing the reply length, syntax, format etc.

1. Write Command
2. Wait ultill you receive command reply, you need parse the reply (you need to know the format, length, syntax of the reply), and based on the reply received do step 3
3. Write next Command / Data
4. Read the reply, parse it and decide next step.
.....

You need to know the format / syntax of the reply, read the reply and make sure you have read the complete reply, (as you know the reply format), then write next command / data

If don't know the reply format, length, syntax etc, I don't think you can fix this.

As always waiting between commands for pre-defined time may help, and again if you plan to run large number of commands in a batch, then this will take long time and will be anoying.

enricong
19th July 2011, 22:20
I am still trying to understand why, but I found that if I add "waitForReadReady()" into the loop where I look for the prompt it works. waitForReadReady() seems to allow me to read more from the output