QProcess problems, output of process

后端 未结 2 1041
别跟我提以往
别跟我提以往 2021-01-06 05:48

I am trying to figure out the use of QProcess. I looked at Qt doc with no luck.
http://doc.qt.io/qt-4.8/qprocess.html

EXAMPLES OF PROBLEM.

2条回答
  •  春和景丽
    2021-01-06 06:14

    Even though Dariusz Scharsig already provided a solution to the problem, I would like to point out what I believe to be the actual problem(s) which can be solved using the signal slot mechanism.

    Problem 1. The condition in your while loop is based on bool QProcess::atEnd () const which is according to QProcess Documentation states:

    Reimplemented from QIODevice::atEnd().

    Returns true if the process is not running, and no more data is available for reading; otherwise returns false.

    But if you looking the documentation for QIODevice::atEnd(), it states:

    Returns true if the current read and write position is at the end of the device (i.e. there is no more data available for reading on the device); otherwise returns false.

    For some devices, atEnd() can return true even though there is more data to read. This special case only applies to devices that generate data in direct response to you calling read() (e.g., /dev or /proc files on Unix and Mac OS X, or console input / stdin on all platforms).

    Solution 1. Change the while loop condition to check the state of your process: while(cmd2.state()!=QProcess::NotRunning){.

    Problem 2. You use cmd2.waitForReadyRead(); outside of the loop. Perhaps some data is ready for reading now and when you finished reading, some more gets made available:

    • you read the commands you just wrote : ipconfig\n
    • ipconfig takes some time to start up and send text to the console. But by then you have already exited your loop because atEnd() gave true even though your process is still running.

    Solution 2. place the waitForReadyRead() inside your loop.

    Consequence 2. waitForReadyRead() will tell you when there is data available, which could be more than one Line, so you should consequently also change the cmd2.ReadLine() to cmd2.ReadAll().

    Problem 3. As documented in QProcess::closeWriteChannel()

    Closing the write channel is necessary for programs that read input data until the channel has been closed.

    Solution 3. One of the following options should work when finished writing your inputs

    • End the process: cmd2.write("exit\n");
    • close the Writechannel: cmd2.closeWriteChannel();

    Working code:

    #include 
    #include 
    #include 
    #include 
    #include     
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        QTextStream qout(stdout);
        QByteArray result;
        QProcess cmd2;
    
        cmd2.setReadChannel(QProcess::StandardOutput);
        cmd2.setProcessChannelMode(QProcess::MergedChannels);
        cmd2.start("cmd");
        if (!cmd2.waitForStarted()){
            qout << "Error: Could not start!" << endl;
            return 0;
        }
        cmd2.write("ipconfig\n");
        cmd2.closeWriteChannel();   //done Writing
    
        while(cmd2.state()!=QProcess::NotRunning){
            cmd2.waitForReadyRead();
            result = cmd2.readAll();
            qout << result;
        }
        qout << endl << "---end----" << endl;
        return a.exec();
    }
    

    I wrote this answer just to explain the way I understand your problem and found a solution but would like to emphasize that the Preferable Solution is to use the Signal/Slot Mechanism as presented by Dariusz.

提交回复
热议问题