Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Qt Service does not enter the event loop issue
Qt 6.12 LTS is out! See what's new in the release blog

Qt Service does not enter the event loop issue

Scheduled Pinned Locked Moved Solved General and Desktop
17 Posts 3 Posters 2.2k 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.
  • Cobra91151C Offline
    Cobra91151C Offline
    Cobra91151
    wrote on last edited by Cobra91151
    #1

    I used the old QtService code from: https://github.com/qtproject/qt-solutions/tree/master/qtservice and created a service to run npm start command which will start my website on Windows startup. When adding -exec argument, starting in app mode it works well but when it runs as a service it does nothing. During a debugging I found out that it does not entering the service event loop correctly. So, I created a small example which should write some text to a txt file to illustrate this issue.

    Code:

    insuranceservice.h

    #ifndef INSURANCESERVICE_H
    #define INSURANCESERVICE_H
    
    #include <QCoreApplication>
    #include <QObject>
    #include <QThread>
    #include <QDebug>
    #include "qtservice.h"
    #include "servicelogger.h"
    
    class InsuranceService : public QtService<QCoreApplication>
    {
        Q_GADGET
    public:
        InsuranceService(int argc, char *argv[]);
        ~InsuranceService();
    
    private:
        void start();
        void stop();
        void pause();
        void resume();
        void processCommand(int code);
        void createApplication(int &argc, char *argv[]);
    };
    
    #endif // INSURANCESERVICE_H
    

    insuranceservice.cpp

    #include "insuranceservice.h"
    
    InsuranceService::InsuranceService(int argc, char *argv[]) : QtService<QCoreApplication>(argc, argv, "InsuranceService")
    {
        std::cout << serviceName().toStdString().c_str() << std::endl;
        setServiceDescription("Test service");
        setServiceFlags(QtServiceBase::CanBeSuspended);
        //setStartupType(QtServiceController::AutoStartup);
    }
    
    void InsuranceService::start()
    {
        try {
            QCoreApplication *insuranceApp = application();
            QFile *logFile = new QFile(ServiceLogger::getLogPath(), insuranceApp); 
            logFile->open(QIODevice::WriteOnly | QIODevice::Append);
            ServiceLogger::writeLog(logFile, QString("Test...").toUtf8());
            logFile->close();
            logFile->deleteLater();
        } catch (...) {
            qCritical() << "Failed to start the service!!!";
        }
    }
    
    void InsuranceService::stop()
    {
    
    }
    
    void InsuranceService::pause()
    {
    
    }
    
    void InsuranceService::resume()
    {
    
    }
    
    void InsuranceService::processCommand(int code)
    {
        Q_UNUSED(code);
    }
    
    void InsuranceService::createApplication(int &argc, char *argv[])
    {
        QtService::createApplication(argc, argv);
    }
    
    InsuranceService::~InsuranceService()
    {
    
    }
    

    main.cpp

    #include <QCoreApplication>
    #include "insuranceservice.h"
    
    int main(int argc, char *argv[])
    {
        InsuranceService service(argc, argv);
        return service.exec();
    }
    

    Any ideas how to enter the service event loop correctly? Thank you.

    C 1 Reply Last reply
    0
    • JonBJ JonB

      @Cobra91151 said in Qt Service does not enter the event loop issue:

      In the Event Viewer it reports: The start method executing....
      But for some reason everything below logMessage() does not execute.

      logFile->open(QIODevice::WriteOnly | QIODevice::Append);

      Why don't you test this result? At the moment you would not know whether anything is executing after logMessage(). That is all I am saying.

      Cobra91151C Offline
      Cobra91151C Offline
      Cobra91151
      wrote on last edited by
      #17

      @JonB @ChrisW67

      Ok. I have properly debug the app and found out that QProcess, QStandardPaths::writableLocation and qgetenv are not working when app is a service. It seems that service functionality is limited. So, I decided to set my app to run at OS startup instead of a service. Now, it works well. The issue is resolved. Thanks.

      1 Reply Last reply
      0
      • Cobra91151C Cobra91151

        I used the old QtService code from: https://github.com/qtproject/qt-solutions/tree/master/qtservice and created a service to run npm start command which will start my website on Windows startup. When adding -exec argument, starting in app mode it works well but when it runs as a service it does nothing. During a debugging I found out that it does not entering the service event loop correctly. So, I created a small example which should write some text to a txt file to illustrate this issue.

        Code:

        insuranceservice.h

        #ifndef INSURANCESERVICE_H
        #define INSURANCESERVICE_H
        
        #include <QCoreApplication>
        #include <QObject>
        #include <QThread>
        #include <QDebug>
        #include "qtservice.h"
        #include "servicelogger.h"
        
        class InsuranceService : public QtService<QCoreApplication>
        {
            Q_GADGET
        public:
            InsuranceService(int argc, char *argv[]);
            ~InsuranceService();
        
        private:
            void start();
            void stop();
            void pause();
            void resume();
            void processCommand(int code);
            void createApplication(int &argc, char *argv[]);
        };
        
        #endif // INSURANCESERVICE_H
        

        insuranceservice.cpp

        #include "insuranceservice.h"
        
        InsuranceService::InsuranceService(int argc, char *argv[]) : QtService<QCoreApplication>(argc, argv, "InsuranceService")
        {
            std::cout << serviceName().toStdString().c_str() << std::endl;
            setServiceDescription("Test service");
            setServiceFlags(QtServiceBase::CanBeSuspended);
            //setStartupType(QtServiceController::AutoStartup);
        }
        
        void InsuranceService::start()
        {
            try {
                QCoreApplication *insuranceApp = application();
                QFile *logFile = new QFile(ServiceLogger::getLogPath(), insuranceApp); 
                logFile->open(QIODevice::WriteOnly | QIODevice::Append);
                ServiceLogger::writeLog(logFile, QString("Test...").toUtf8());
                logFile->close();
                logFile->deleteLater();
            } catch (...) {
                qCritical() << "Failed to start the service!!!";
            }
        }
        
        void InsuranceService::stop()
        {
        
        }
        
        void InsuranceService::pause()
        {
        
        }
        
        void InsuranceService::resume()
        {
        
        }
        
        void InsuranceService::processCommand(int code)
        {
            Q_UNUSED(code);
        }
        
        void InsuranceService::createApplication(int &argc, char *argv[])
        {
            QtService::createApplication(argc, argv);
        }
        
        InsuranceService::~InsuranceService()
        {
        
        }
        

        main.cpp

        #include <QCoreApplication>
        #include "insuranceservice.h"
        
        int main(int argc, char *argv[])
        {
            InsuranceService service(argc, argv);
            return service.exec();
        }
        

        Any ideas how to enter the service event loop correctly? Thank you.

        C Offline
        C Offline
        ChrisW67
        wrote on last edited by
        #2

        @Cobra91151 The service will, by default, be running as a system account with no access to things like network shares, environment variables (PATH etc), console IO, etc. When you run it from a command prompt it has these things.

        What can be going wrong is very dependent on exactly what your npm and app instance needs.

        Cobra91151C 1 Reply Last reply
        2
        • C ChrisW67

          @Cobra91151 The service will, by default, be running as a system account with no access to things like network shares, environment variables (PATH etc), console IO, etc. When you run it from a command prompt it has these things.

          What can be going wrong is very dependent on exactly what your npm and app instance needs.

          Cobra91151C Offline
          Cobra91151C Offline
          Cobra91151
          wrote on last edited by Cobra91151
          #3

          @ChrisW67

          Yes, you are right. So, how to provide to this service the access to all these things: environment variables (PATH etc), console IO, etc?

          There are a lot of other services which do something, for example Google Update service etc.

          Thanks.

          C 1 Reply Last reply
          0
          • Cobra91151C Cobra91151

            @ChrisW67

            Yes, you are right. So, how to provide to this service the access to all these things: environment variables (PATH etc), console IO, etc?

            There are a lot of other services which do something, for example Google Update service etc.

            Thanks.

            C Offline
            C Offline
            ChrisW67
            wrote on last edited by
            #4

            @Cobra91151 I am not a real Node.js person. Does this help?

            Cobra91151C 1 Reply Last reply
            0
            • C ChrisW67

              @Cobra91151 I am not a real Node.js person. Does this help?

              Cobra91151C Offline
              Cobra91151C Offline
              Cobra91151
              wrote on last edited by Cobra91151
              #5

              @ChrisW67

              I already tried node-windows but it fails for me. That's why I decided to write my own service.

              I think, I know what is wrong. I found a similar issue: https://stackoverflow.com/questions/10027306/windows-service-doesnt-execute-onstart

              All you should really do in the start event is fire up a worker thread that will run as long as your service is active and do the actual processing. You can use a BackgroundWorker component to simplify this. When the service is stopped you do any necessary cleanup, and terminate the background thread.

              I should create the worker class and a thread and do all processing there. start() method should call Worker class with QThread, stop() method should stop the thread and clear all resources. I think, the app event loop goes out of scope or something else occurs when in a service mode. Thanks.

              Cobra91151C 1 Reply Last reply
              0
              • Cobra91151C Cobra91151

                @ChrisW67

                I already tried node-windows but it fails for me. That's why I decided to write my own service.

                I think, I know what is wrong. I found a similar issue: https://stackoverflow.com/questions/10027306/windows-service-doesnt-execute-onstart

                All you should really do in the start event is fire up a worker thread that will run as long as your service is active and do the actual processing. You can use a BackgroundWorker component to simplify this. When the service is stopped you do any necessary cleanup, and terminate the background thread.

                I should create the worker class and a thread and do all processing there. start() method should call Worker class with QThread, stop() method should stop the thread and clear all resources. I think, the app event loop goes out of scope or something else occurs when in a service mode. Thanks.

                Cobra91151C Offline
                Cobra91151C Offline
                Cobra91151
                wrote on last edited by Cobra91151
                #6

                I updated the main post.

                Additionally, I will create the logger to check what exectly executes in the start method.

                1 Reply Last reply
                0
                • Cobra91151C Offline
                  Cobra91151C Offline
                  Cobra91151
                  wrote on last edited by
                  #7

                  So, I have found out that even with QCoreApplication *insuranceApp = application(); it does not entering the event loop correctly. What's why it does not execute my code. The question is how to enter the service event loop? Thanks.

                  Cobra91151C 1 Reply Last reply
                  0
                  • Cobra91151C Cobra91151

                    So, I have found out that even with QCoreApplication *insuranceApp = application(); it does not entering the event loop correctly. What's why it does not execute my code. The question is how to enter the service event loop? Thanks.

                    Cobra91151C Offline
                    Cobra91151C Offline
                    Cobra91151
                    wrote on last edited by Cobra91151
                    #8

                    I tried to run this service with the built-in logMessage method:

                    void InsuranceService::start()
                    {
                        logMessage("The start method executing....", QtServiceBase::Success, 0, 0);
                        QFile *logFile = new QFile(ServiceLogger::getLogPath());
                        logFile->open(QIODevice::WriteOnly | QIODevice::Append);
                        ServiceLogger::writeLog(logFile, QString("Test...").toUtf8());
                        logFile->close();
                        logFile->deleteLater();
                    }
                    

                    In the Event Viewer it reports: The start method executing....
                    But for some reason everything below logMessage() does not execute. The log file does not exists which should be created. It could be the issue that logMessage() runs on one instance and QFile creates/runs on another instance. I need somehow to connect to the right instance.

                    Cobra91151C JonBJ 3 Replies Last reply
                    0
                    • Cobra91151C Cobra91151

                      I tried to run this service with the built-in logMessage method:

                      void InsuranceService::start()
                      {
                          logMessage("The start method executing....", QtServiceBase::Success, 0, 0);
                          QFile *logFile = new QFile(ServiceLogger::getLogPath());
                          logFile->open(QIODevice::WriteOnly | QIODevice::Append);
                          ServiceLogger::writeLog(logFile, QString("Test...").toUtf8());
                          logFile->close();
                          logFile->deleteLater();
                      }
                      

                      In the Event Viewer it reports: The start method executing....
                      But for some reason everything below logMessage() does not execute. The log file does not exists which should be created. It could be the issue that logMessage() runs on one instance and QFile creates/runs on another instance. I need somehow to connect to the right instance.

                      Cobra91151C Offline
                      Cobra91151C Offline
                      Cobra91151
                      wrote on last edited by
                      #9

                      Additionally, I created a test method in QtServiceBase class.

                      void QtServiceBase::myCustomMessage(QString path)
                      {
                          QFile *file = new QFile(path);
                          file->open(QIODevice::WriteOnly);
                          file->write("This is just a test example....");
                          file->close();
                          file->deleteLater();
                      }
                      

                      And in InsuranceService class I call my myCustomMessage() test method.

                      void InsuranceService::start()
                      {
                          logMessage("The start method executing....", QtServiceBase::Success, 0, 0);
                          myCustomMessage("C:\\Users\\cobra\\AppData\\Local\\InsuranceService\\Log\\Test.txt");
                      }
                      

                      Now it creates the .txt file in the service! So, I was right. The issue is with the wrong instance.
                      Have anyone tried the QtService to share some details about this issue? Thanks.

                      1 Reply Last reply
                      0
                      • Cobra91151C Cobra91151

                        I tried to run this service with the built-in logMessage method:

                        void InsuranceService::start()
                        {
                            logMessage("The start method executing....", QtServiceBase::Success, 0, 0);
                            QFile *logFile = new QFile(ServiceLogger::getLogPath());
                            logFile->open(QIODevice::WriteOnly | QIODevice::Append);
                            ServiceLogger::writeLog(logFile, QString("Test...").toUtf8());
                            logFile->close();
                            logFile->deleteLater();
                        }
                        

                        In the Event Viewer it reports: The start method executing....
                        But for some reason everything below logMessage() does not execute. The log file does not exists which should be created. It could be the issue that logMessage() runs on one instance and QFile creates/runs on another instance. I need somehow to connect to the right instance.

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by
                        #10

                        @Cobra91151 said in Qt Service does not enter the event loop issue:

                        But for some reason everything below logMessage() does not execute

                        logFile->open(QIODevice::WriteOnly | QIODevice::Append);
                        

                        How do you know this does not execute? The very first thing I would do is check the return result and report details of any failure.

                        Could you have a file permission issue? You have to be careful about the paths you pass to open and the permissions you are currently executing under.

                        Cobra91151C 1 Reply Last reply
                        1
                        • JonBJ JonB

                          @Cobra91151 said in Qt Service does not enter the event loop issue:

                          But for some reason everything below logMessage() does not execute

                          logFile->open(QIODevice::WriteOnly | QIODevice::Append);
                          

                          How do you know this does not execute? The very first thing I would do is check the return result and report details of any failure.

                          Could you have a file permission issue? You have to be careful about the paths you pass to open and the permissions you are currently executing under.

                          Cobra91151C Offline
                          Cobra91151C Offline
                          Cobra91151
                          wrote on last edited by Cobra91151
                          #11

                          @JonB

                          I just run InsuranceService.exe -exec in cmd and it works beause I see the file is created and data is written there as well. When I run NET START InsuranceService command, the service is started and running but no file is created.

                          Also, I add my test method to QtServiceBase class and call it, then the file automatically creates when I start my service. Additionally, the program has the admin privileges.

                          I think the issue could be with the static Qt build, which could take some internal files and override them. I had some similar issues with QFtp class. I will try to use Qt shared build and provide all dlls components.

                          JonBJ 1 Reply Last reply
                          0
                          • Cobra91151C Cobra91151

                            @JonB

                            I just run InsuranceService.exe -exec in cmd and it works beause I see the file is created and data is written there as well. When I run NET START InsuranceService command, the service is started and running but no file is created.

                            Also, I add my test method to QtServiceBase class and call it, then the file automatically creates when I start my service. Additionally, the program has the admin privileges.

                            I think the issue could be with the static Qt build, which could take some internal files and override them. I had some similar issues with QFtp class. I will try to use Qt shared build and provide all dlls components.

                            JonBJ Offline
                            JonBJ Offline
                            JonB
                            wrote on last edited by
                            #12

                            @Cobra91151 I suggested what I would do.

                            Cobra91151C 1 Reply Last reply
                            0
                            • JonBJ JonB

                              @Cobra91151 I suggested what I would do.

                              Cobra91151C Offline
                              Cobra91151C Offline
                              Cobra91151
                              wrote on last edited by Cobra91151
                              #13

                              @JonB

                              I already tried to log every step, anything after myCustomMessage("C:\\Users\\cobra\\AppData\\Local\\InsuranceService\\Log\\Test.txt"); will NOT execute. At this moment I do not know what is the reason for such behaviour. The app runs just fine but when it is the service it does nothing.

                              Cobra91151C 1 Reply Last reply
                              0
                              • Cobra91151C Cobra91151

                                @JonB

                                I already tried to log every step, anything after myCustomMessage("C:\\Users\\cobra\\AppData\\Local\\InsuranceService\\Log\\Test.txt"); will NOT execute. At this moment I do not know what is the reason for such behaviour. The app runs just fine but when it is the service it does nothing.

                                Cobra91151C Offline
                                Cobra91151C Offline
                                Cobra91151
                                wrote on last edited by Cobra91151
                                #14

                                @JonB

                                It only executes the QtServiceBase methods. I can show you the example, you will see it one moment.

                                When I hardcoded the file path to: "C:\\Users\\cobra\\AppData\\Local\\InsuranceService\\Log\\text.txt" it successfully created the file. It seems the issue is with: QStandardPaths::writableLocation(QStandardPaths::DataLocation) but I need to debug it again. Thanks.

                                1 Reply Last reply
                                0
                                • Cobra91151C Cobra91151

                                  I tried to run this service with the built-in logMessage method:

                                  void InsuranceService::start()
                                  {
                                      logMessage("The start method executing....", QtServiceBase::Success, 0, 0);
                                      QFile *logFile = new QFile(ServiceLogger::getLogPath());
                                      logFile->open(QIODevice::WriteOnly | QIODevice::Append);
                                      ServiceLogger::writeLog(logFile, QString("Test...").toUtf8());
                                      logFile->close();
                                      logFile->deleteLater();
                                  }
                                  

                                  In the Event Viewer it reports: The start method executing....
                                  But for some reason everything below logMessage() does not execute. The log file does not exists which should be created. It could be the issue that logMessage() runs on one instance and QFile creates/runs on another instance. I need somehow to connect to the right instance.

                                  JonBJ Offline
                                  JonBJ Offline
                                  JonB
                                  wrote on last edited by
                                  #15

                                  @Cobra91151 said in Qt Service does not enter the event loop issue:

                                  In the Event Viewer it reports: The start method executing....
                                  But for some reason everything below logMessage() does not execute.

                                  logFile->open(QIODevice::WriteOnly | QIODevice::Append);

                                  Why don't you test this result? At the moment you would not know whether anything is executing after logMessage(). That is all I am saying.

                                  Cobra91151C 2 Replies Last reply
                                  1
                                  • JonBJ JonB

                                    @Cobra91151 said in Qt Service does not enter the event loop issue:

                                    In the Event Viewer it reports: The start method executing....
                                    But for some reason everything below logMessage() does not execute.

                                    logFile->open(QIODevice::WriteOnly | QIODevice::Append);

                                    Why don't you test this result? At the moment you would not know whether anything is executing after logMessage(). That is all I am saying.

                                    Cobra91151C Offline
                                    Cobra91151C Offline
                                    Cobra91151
                                    wrote on last edited by
                                    #16

                                    @JonB

                                    I will debug it again because it seems some code is skipped when running it as a service. Thank you.

                                    1 Reply Last reply
                                    0
                                    • JonBJ JonB

                                      @Cobra91151 said in Qt Service does not enter the event loop issue:

                                      In the Event Viewer it reports: The start method executing....
                                      But for some reason everything below logMessage() does not execute.

                                      logFile->open(QIODevice::WriteOnly | QIODevice::Append);

                                      Why don't you test this result? At the moment you would not know whether anything is executing after logMessage(). That is all I am saying.

                                      Cobra91151C Offline
                                      Cobra91151C Offline
                                      Cobra91151
                                      wrote on last edited by
                                      #17

                                      @JonB @ChrisW67

                                      Ok. I have properly debug the app and found out that QProcess, QStandardPaths::writableLocation and qgetenv are not working when app is a service. It seems that service functionality is limited. So, I decided to set my app to run at OS startup instead of a service. Now, it works well. The issue is resolved. Thanks.

                                      1 Reply Last reply
                                      0
                                      • Cobra91151C Cobra91151 has marked this topic as solved on
                                      • Cobra91151C Cobra91151 has marked this topic as unsolved on
                                      • Cobra91151C Cobra91151 has marked this topic as solved on

                                      • Login

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