Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

I can redirect output of gzip, but cannot redirect output of java.



  • It's on Windows 10. The following code can redirect output of gzip to display its help info:

    #include <QCoreApplication>
    #include <QProcess>
    #include <iostream>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        std::cout << "Main process ID: " << a.applicationPid() << "\n";
        QStringList args;
        args << "-h";
        QProcess process;
        process.setProgram("C:\\Program Files (x86)\\GnuWin32\\bin\\gzip.exe");
        process.setArguments(args);
        process.start();
        process.waitForStarted();
        std::cout << "Process started: " << process.processId() << std::endl;
        process.waitForReadyRead();
        std::cout << process.readAll().toStdString() << std::endl;
        process.close();
        return 0;
    }
    

    But if I change gzip to java, i.e., replace the setProgram line to:

    process.setProgram("C:\\Program Files (x86)\\Common Files\\Oracle\\Java\\javapath\\java.exe");
    

    , it is expected that the help info of java be output. But there is no such info printed out in the application's console window. I have double checked that the path is correct and the process ID of java indicates that it is started correctly. So what is wrong with my code? How to fix it? Thank you.


  • Lifetime Qt Champion

    @zzzhhhzzzhhh Is it possible that java outputs to stderr?



  • QProcess::readAll() will only read the read channel currently selected, which, I guess, is stdout by default. To read all output including stderr, you need to call also QProcess::readAllStandardError().

        process.waitForReadyRead();
        std::cout << process.readAllStandardOutput().toStdString() << std::endl;
        std::cout << process.readAllStandardError().toStdString() << std::endl;
        process.close();
    

    The disadvantage of this is that you will lose the order of the messages as you will display all standard output messages before error messages.

    So I would recommend using signals QProcess::readyReadStandardOutput() and QProcess::readyReadStandardError() :

    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
        std::cout << "Main process ID: " << a.applicationPid() << "\n";
        QStringList args;
        args << "-h";
        QProcess process;
        process.setProgram("C:\\Program Files (x86)\\GnuWin32\\bin\\gzip.exe");
        process.setArguments(args);
    
        QObject::connect(&process, &QProcess::readyReadStandardError, [&process]{
           std::cerr << process.readAllStandardError().toStdString();
        });
    
        QObject::connect(&process, &QProcess::readyReadStandardOutput, [&process]{
           std::cout << process.readAllStandardOutput().toStdString();
        });
    
        process.start();
        process.waitForStarted();
        std::cout << "Process started: " << process.processId() << std::endl;
        process.waitForFinished();
        
        process.close();
        return 0;
    }
    

    [edit: Fixed code SGaist]



  • @Gojir4 said in I can redirect output of gzip, but cannot redirect output of java.:

    process.waitForFinished();

    Thank you for the reply. But there are some syntax errors:

    alt text
    It's beyond my capability to fix them, so could you please help me with it? Thanks.


  • Lifetime Qt Champion

    Hi,

    The sample has been updated.



  • @SGaist Thank you



  • @SGaist Thank you so much for your help!



  • @jsulm So according to Gojir4's code, java outputs to stderr (at least for -h).


Log in to reply