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

QProcess not able (?) to start a Qt application



  • Hi Forum
    I have a very large Qt application, say LA, which at some point needs to start a smaller Qt application, say SA, which has been built separately (essentially a widget for data analysis, which I don't want to compile within the large code).
    I used, as in many other part of LA, the QProcess paradigma (create a QProcess on the heap, define program, define list of arguments, call start with wait for finished). This is not working for the Qt SA.
    Note:

    1. The SA.exe has it's own directory with the deployment libraries (so it can be launched with a d-click, or by the cmd command line).
    2. in LA QProcess has been successfully used for non-Qt programs

    Any idea?
    Thanks in advance
    Giovanni


  • Moderators

    @gbettega
    as I'm using Process to start other Qt-based applications, I can say it works fine.

    Whats your OS and QtVersion ?
    Can you show us your QProcess code?



  • @gbettega
    As @J-Hilk says we need to see code.
    Your code should be checking for errors (inc. any exit code) and importantly should be capturing stderr at launch time so that we can see any OS error message. That might be telling you what you need to know.
    Does SA.exe work if its current/working directory is not where the .exe is?



  • Hello,
    Windows 10, Qt 5.8.0 MSVC 2015

    The application I'm trying to start is TimeStepBuilder.exe

    QProcess *shellP = new QProcess(this);
    QString program = QString::fromLatin1(std::getenv("TIMESTEPBUILDER_PATH"))+"\\TimeStepBuilder.exe";
    
    cout<<"____"<<program.toStdString()<<"____"<<endl;
        system("D:\\Work\\Qt\\TimeStepBuilder\\TimeStepBuilderBuild\\release\\TimeStepBuilder.exe");
    
    QStringList arguments;
    arguments<<tools::getWorkingDir()<<timeHistoryFileLoc;
        
    shellP->setProgram(program);
    shellP->setArguments(arguments);
    shellP->start();
    shellP->waitForFinished(-1);
    int exitCode = shellP->exitCode();
        
    cout<<"___exit code: "<<exitCode<<"____"<<endl;
    ...
    

    Exit code = 0 if waitForFinished(-1) is commented
    Exit code = -1073741511 if not

    I cannot understand at all...

    The picture shows the TimeStepBuilder.exe application
    Thanks
    Giovanni

    tsb.png



  • @gbettega
    You really need to use the signals/slots to check for errors, and capture stderr to see if an error is being reported, if you expect to sort this out (should be in production code anyway, what do you expect end user to do if errors are being reported and nothing is looking at them?)

    Why does your code already run the program once via system()? Is there an issue about having 2 instances running?



  • Sorry, this is the right code.
    The SA.exe file does not start if called from outside its directory (no env variable has been set for it):
    indeed the program string contains the absolute path, retrieved from an user env variable.
    TimeStepBuilder.exe (SA.exe) starts normally when launched from the windows shell.
    Regards
    Giovanni

        const QString &timeHistoryFileLoc = curNode->getPropertyValue<QString>("Time history file");
    
        QProcess *shellP = new QProcess(this);
        QString program = QString::fromLatin1(std::getenv("TIMESTEPBUILDER_PATH"))+"\\TimeStepBuilder.exe";
        cout<<"____"<<program.toStdString()<<"____"<<endl;
        QStringList arguments;
        arguments<<tools::getWorkingDir()<<timeHistoryFileLoc;
    
        shellP->setProgram(program);
        shellP->setArguments(arguments);
        shellP->start();
        shellP->waitForFinished(-1);
        int exitCode = shellP->exitCode();
    
        cout<<"___exit code: "<<exitCode<<"____"<<endl;
    
    


  • @gbettega

    @JonB wrote:

    You really need to use the signals/slots to check for errors, and capture stderr to see if an error is being reported, if you expect to sort this out (should be in production code anyway, what do you expect end user to do if errors are being reported and nothing is looking at them?)

    No point ignoring this.



  • Hello
    I do not need points. This is not Champions League. Just for info, I made

    connect(shellP,SIGNAL(readyReadStandardError()),this,SLOT(captureErr()));

    where the slot accesses the shellP (made public) write on stderr, and immediately exit(<error code>).
    No error is detected
    Regards
    Giovanni


  • Lifetime Qt Champion

    Hi
    try
    shellP->setWorkingDirectory( std::getenv("TIMESTEPBUILDER_PATH") );

    It might be that the Qt program cannot find its support DLLs when called via QProcess.



  • Thank you very much mrjj for your suggestion. I discovered it is something related to your observation.
    Actually, at the moment , the LargeApplication is launched from the QtCreator, so the .exe files loads the .dll from the Qt directory. There is not a deployment for LA.

    Instead, the SmallApplication SA.exe loads the Qt dll from its own distribution directory, since it exists as a deployment.

    When launching the Large App from Creator and then using the Qt process for launching in turn the SmallApp some .dll conflict arise (actually more than one).

    Indeed I solved by:

    1. copying the SmallApp exe into the build directory of the Large App one
    2. building the depolyment of SmallApp in that dir
    3. deleting unecessary .dll (which avoid the main app from starting from the Qt Creator)

    and it works.
    QProcess.PNG Regards


Log in to reply