Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Unable to launch QT desktop app from Qt Service using QProcess
Forum Update on Monday, May 27th 2025

Unable to launch QT desktop app from Qt Service using QProcess

Scheduled Pinned Locked Moved Unsolved General and Desktop
10 Posts 3 Posters 171 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Sikander Rafiq
    wrote last edited by
    #1

    HI,
    I want to launch my QT desktop app when Windows is shutting down. In order to do this, I have created Qt service in which we want to do the followings;

    • Intercept/capture Windows/Mac shutdown process using WM_QUERYENDSESSION event capture. But, I am still unable to capture this event
    • return result = 0; to halt shut down process
    • launch QT desktop app using QProcess (unable to launch it from QT service, though same code able to launch the other instance of app from desktop app. I have able to run Qt service in user session, but still QT desktop app is not launched from service

    Here is my code to capture WM_QUERYENDSESSION native event

    class ShutdownEventFilter : public QAbstractNativeEventFilter
    {
    public:
        explicit ShutdownEventFilter(QObject *parent = nullptr);
    
        void launchApp();
    
    protected:
        virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) override;
    
    signals:
    };
    
    ShutdownEventFilter::ShutdownEventFilter(QObject *parent)
        : QAbstractNativeEventFilter()
    {}
    
    bool ShutdownEventFilter::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
    {
        if (eventType == "windows_generic_MSG") {
            MSG *msg = static_cast<MSG*>(message);
            if (msg->message == WM_QUERYENDSESSION) {
                Logging::getInstance()->writeLog("ShutdownEventFilter::nativeEventFilter::WM_QUERYENDSESSION------------blocing shutdown-----");
                //-ShutdownBlockReasonCreate(msg->hwnd, L"Don't shutdown");
                *result = 0; // Returning 1 allows the shutdown to proceed, 0 cancels it
                return true; // Consume the message, preventing further processing
            } else if (msg->message == WM_ENDSESSION) {
                Logging::getInstance()->writeLog("ShutdownEventFilter::nativeEventFilter::WM_ENDSESSION-----------shutting donw-----");
                qApp->quit(); // Gracefully quit application
            }
        }
        return false; // handled by QT framework
    }
    
    void ShutdownEventFilter::launchApp()
    {
        Logging::getInstance()->writeLog("ShutdownEventFilter::launchApp");
        QString program = "D:/Work/Qt_builds/inspirationalclips_Qt_6_8_0_MSVC2022_64bit-Debug/debug/inspirationalclips.exe";
        QStringList arguments;
        // Add arguments if needed, e.g., arguments << "-flag" << "value";
    
        QProcess *process = new QProcess();
        QObject::connect(process, &QProcess::errorOccurred, [&](QProcess::ProcessError error) {
            qDebug() << "Process error:" << error << process->errorString();
            Logging::getInstance()->writeLog("Process error:: " + process->errorString());
        });
        process->start(program, arguments);
    
        if (!process->waitForStarted()) {
            qDebug() << "Error starting application:" << process->errorString();
            Logging::getInstance()->writeLog("Error starting application: " + process->errorString());
        }
    
        // The process will continue to run independently
        // if you need to interact with it, use other QProcess methods
        Logging::getInstance()->writeLog("ShutdownEventFilter::launchApp App running-------------------");
    }
    
    

    Here is the code to register the event filter in QT service start function.

    class MainService : public QtService<QApplication>
    {
    public:
        /**
         * @brief The constructor
         * @param argc
         * @param argv
         */
        MainService(int argc, char **argv);
    
        /**
         * @brief The destructor
         */
        ~MainService();
    
        /**
         * @brief Start the service
         */
        void start();
    };
    
    void MainService::start()
    {
        try
        {
            qApp->setApplicationName("InspirationalClipsService");
            qDebug() << "InspirationalClips Service started!";
            qDebug() << qApp->applicationDirPath();
    
            ShutdownEventFilter shutdownfilter;
            qApp->installNativeEventFilter(&shutdownfilter);
            shutdownfilter.launchApp();
        }
        catch(...)
        {
            qCritical() << "An unknown error in the start";
        }
    }
    
    1 Reply Last reply
    0
    • S Offline
      S Offline
      Sikander Rafiq
      wrote last edited by
      #2

      @SGaist any expert comments on this! Thanks in advance for your time and cooperation.

      jsulmJ 1 Reply Last reply
      0
      • S Offline
        S Offline
        Sikander Rafiq
        wrote last edited by
        #3

        I am using QT5.15.2 for Qt service and my desktop QT app is written in QT6.8.

        1 Reply Last reply
        0
        • S Sikander Rafiq referenced this topic
        • S Offline
          S Offline
          Sikander Rafiq
          wrote last edited by
          #4

          Currently I am using Windows 10, but I need this functionality on Windows 11 and Mac as well.

          1 Reply Last reply
          0
          • S Sikander Rafiq

            @SGaist any expert comments on this! Thanks in advance for your time and cooperation.

            jsulmJ Online
            jsulmJ Online
            jsulm
            Lifetime Qt Champion
            wrote last edited by
            #5

            @Sikander-Rafiq said in Unable to launch QT desktop app from Qt Service using QProcess:

            @SGaist any expert comments on this!

            No need to address people directly like this. If somebody has to say something he/she will do.

            I see you have some error handling, but you do not say whether you see any errors printed.

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • S Offline
              S Offline
              Sikander Rafiq
              wrote last edited by
              #6

              No error printed, but desktop app not launched.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                Sikander Rafiq
                wrote last edited by
                #7

                Hi,
                I have added more error handling code to investigate what happened with new Process. The error logs shows that process is immediately terminated after started - don't know why. Investigating it.

                void ShutdownEventFilter::launchApp()
                {
                    Logging::getInstance()->writeLog("ShutdownEventFilter::launchApp");
                    QString program = "D:/Work/Qt_builds/inspirationalclips_Qt_6_8_0_MSVC2022_64bit-Debug/debug/inspirationalclips.exe";
                    QStringList arguments;
                    // Add arguments if needed, e.g., arguments << "-flag" << "value";
                
                    QProcess *process = new QProcess();
                    QObject::connect(process, &QProcess::errorOccurred, [&](QProcess::ProcessError error) {
                        qDebug() << "Process error:" << error << process->errorString();
                        Logging::getInstance()->writeLog("Process error:: " + process->errorString());
                    });
                    QObject::connect(process, &QProcess::readyReadStandardOutput, [=]() {
                        Logging::getInstance()->writeLog("Process::readyReadStandardOutput: " + process->readAllStandardOutput());
                    });
                    QObject::connect(process, &QProcess::readAllStandardError, [=]() {
                        Logging::getInstance()->writeLog("Process::readAllStandardError: " + process->readAllStandardError());
                    });
                    QObject::connect(process, &QProcess::started, [=]() {
                        Logging::getInstance()->writeLog("Process::started: ");
                    });
                    QObject::connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                        [&](int exitCode, QProcess::ExitStatus exitStatus) {
                            QString strText = QString("processFinished: exitCode=%1").arg(exitCode);
                            Logging::getInstance()->writeLog(strText);
                
                            QString strExitStatus = QMetaEnum::fromType<QProcess::ExitStatus>().valueToKey(exitStatus);
                            strText = QString("processFinished: exitStatus=%1").arg(strExitStatus);
                            Logging::getInstance()->writeLog(strText);
                        });
                
                    process->start(program, arguments);
                
                    if (!process->waitForStarted()) {
                        qDebug() << "Error starting application:" << process->errorString();
                        Logging::getInstance()->writeLog("Error starting application: " + process->errorString());
                    }
                
                    QProcess::ProcessState state = process->state();
                    QString strState = QMetaEnum::fromType<QProcess::ProcessState>().valueToKey(state);
                    QString strText = QString("ShutdownEventFilter::state state=%1").arg(strState);
                    Logging::getInstance()->writeLog(strText);
                
                    // The process will continue to run independently
                    // if you need to interact with it, use other QProcess methods
                    Logging::getInstance()->writeLog("ShutdownEventFilter::launchApp----------running fine-------");
                }
                

                Here are logs what I get:

                2025-05-14 18:24:37: ShutdownEventFilter::launchApp
                2025-05-14 18:24:37: Process::started:
                2025-05-14 18:24:37: ShutdownEventFilter::state state=Running
                2025-05-14 18:24:37: ShutdownEventFilter::launchApp----------running fine-------
                2025-05-14 18:24:39: processFinished: exitCode=255
                2025-05-14 18:24:39: processFinished: exitStatus=NormalExit

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote last edited by
                  #8

                  Hi,

                  Did you properly deploy the Qt application you are starting ?
                  If not, it will not necessarily find its dependencies and thus fail to start. So first thing I would do is ensure that it can start from where you are calling it outside of Qt Creator.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    Sikander Rafiq
                    wrote last edited by
                    #9

                    Hi,
                    Yes, the desktop app can be started directly if we paste its path
                    (i.e. D:/Work/Qt_builds/inspirationalclips_Qt_6_8_0_MSVC2022_64bit-Debug/debug/inspirationalclips.exe) in window explorer.

                    The same code can launch another instance of the desktop app if called from the QT desktop app itself.

                    There is some issue due to QT service (as we want to launch it from service). As I said, Qt service is running in the current user's session (in which I login to Windows10).

                    One difference I have noted, when the app launched from QT app, then exitCode is 0 (as below)
                    2025-05-14 20:41:06: processFinished: exitCode = 0
                    2025-05-14 20:41:06: processFinished: exitStatus = NormalExit

                    When this is launched from QT service, the exitCode is 255 (as below)
                    2025-05-14 20:43:46: processFinished: exitCode = 255
                    2025-05-14 20:43:46: processFinished: exitStatus = NormalExit

                    Although exitStatus is the same in both cases (i.e., NormalExit)

                    My other question is does QT (especially QT 5.15.2) not supporting to capture WM_QUERYENDSESSION native event?

                    Thanks for your time to help!

                    1 Reply Last reply
                    0
                    • S Offline
                      S Offline
                      Sikander Rafiq
                      wrote last edited by Sikander Rafiq
                      #10

                      I have logged process state changed event and few more. Here is the updated code and logs.

                      void ShutdownEventFilter::launchApp()
                      {
                          Logging::getInstance()->writeLog("ShutdownEventFilter::launchApp");
                      
                          QString workingDir = "D:/Work/Qt_builds/inspirationalclips_Qt_6_8_0_MSVC2022_64bit-Debug/debug/";
                          QString program = "D:/Work/Qt_builds/inspirationalclips_Qt_6_8_0_MSVC2022_64bit-Debug/debug/inspirationalclips.exe";
                          QStringList arguments;
                          // Add arguments if needed, e.g., arguments << "-flag" << "value";
                      
                          QProcess *process = new QProcess();
                      
                          //standard output:
                          QObject::connect(process, &QProcess::readyReadStandardOutput, [=]() {
                              Logging::getInstance()->writeLog("QProcess::readyReadStandardOutput: " + process->readAllStandardOutput());
                          });
                          QObject::connect(process, &QProcess::readAllStandardOutput, [=]() {
                              QString strText = QString("QProcess::readAllStandardOutput: output = %1")
                                  .arg(QString::fromUtf8(process->readAllStandardOutput()));
                              Logging::getInstance()->writeLog(strText);
                          });
                      
                          //standard errors:
                          QObject::connect(process, &QProcess::errorOccurred, [&](QProcess::ProcessError error) {
                              Logging::getInstance()->writeLog("QProcess::errorOccurred: " + process->errorString());
                          });
                          QObject::connect(process, &QProcess::readyReadStandardError, [=]() {
                              QProcess::ProcessError procErr = process->error();
                              QString strErr = QMetaEnum::fromType<QProcess::ProcessError>().valueToKey(procErr);
                              QString strText = QString("QProcess::readyReadStandardError: error = %1").arg(strErr);
                              Logging::getInstance()->writeLog(strText);
                          });
                          QObject::connect(process, &QProcess::readAllStandardError, [=]() {
                              Logging::getInstance()->writeLog("QProcess::readAllStandardError: " + process->readAllStandardError());
                          });
                      
                          QObject::connect(process, &QProcess::stateChanged, [&](QProcess::ProcessState state) {
                              QString strState = QMetaEnum::fromType<QProcess::ProcessState>().valueToKey(state);
                              QString strText  = QString("QProcess::stateChanged: state = %1").arg(strState);
                              Logging::getInstance()->writeLog(strText);
                          });
                          QObject::connect(process, &QProcess::started, [=]() {
                              Logging::getInstance()->writeLog("QProcess::started: -----------process started---");
                          });
                          QObject::connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                              [&](int exitCode, QProcess::ExitStatus exitStatus) {
                                  QString strExitStatus = QMetaEnum::fromType<QProcess::ExitStatus>().valueToKey(exitStatus);
                                  QString strText = QString("QProcess::finished: exitCode = %1 exitStatus = %2")
                                                .arg(exitCode)
                                                .arg(strExitStatus);
                                  Logging::getInstance()->writeLog(strText);
                              });
                      
                          process->setWorkingDirectory(workingDir);
                          process->start(program, arguments);
                      
                          if (!process->waitForStarted()) {
                              qDebug() << "Error starting application:" << process->errorString();
                              Logging::getInstance()->writeLog("Error starting application: " + process->errorString());
                          }
                      
                          //print current state
                          QProcess::ProcessState state = process->state();
                          QString strState = QMetaEnum::fromType<QProcess::ProcessState>().valueToKey(state);
                          QString strText = QString("ShutdownEventFilter::state = %1").arg(strState);
                          Logging::getInstance()->writeLog(strText);
                      
                          //print error if any:
                          QProcess::ProcessError procErr = process->error();
                          QString strErr = QMetaEnum::fromType<QProcess::ProcessError>().valueToKey(procErr);
                          strText = QString("ShutdownEventFilter::error = %1").arg(strErr);
                          Logging::getInstance()->writeLog(strText);
                      
                          // The process will continue to run independently
                          // if you need to interact with it, use other QProcess methods
                          Logging::getInstance()->writeLog("ShutdownEventFilter::launchApp----------running------");
                      }
                      

                      Here is the updated log file:

                      2025-05-15 15:05:49: ShutdownEventFilter::launchApp
                      2025-05-15 15:05:49: QProcess::stateChanged: state = Starting
                      2025-05-15 15:05:49: QProcess::stateChanged: state = Running
                      2025-05-15 15:05:49: QProcess::started: -----------process started---
                      2025-05-15 15:05:49: ShutdownEventFilter::state = Running
                      2025-05-15 15:05:49: ShutdownEventFilter::error = UnknownError
                      2025-05-15 15:05:49: ShutdownEventFilter::launchApp----------running------
                      2025-05-15 15:05:51: QProcess::stateChanged: state = NotRunning
                      2025-05-15 15:05:51: QProcess::finished: exitCode = 255 exitStatus = NormalExit

                      This logs shows process started and then goto ''Running' state and then Unknown error occurred and process terminated.

                      1 Reply Last reply
                      0
                      • A AlbertoJ2 referenced this topic

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved