Qt Service does not enter the event loop issue
-
I used the old QtService code from: https://github.com/qtproject/qt-solutions/tree/master/qtservice and created a service to run
npm startcommand which will start my website on Windows startup. When adding-execargument, 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_Hinsuranceservice.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.
-
@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.Ok. I have properly debug the app and found out that
QProcess,QStandardPaths::writableLocationandqgetenvare 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. -
I used the old QtService code from: https://github.com/qtproject/qt-solutions/tree/master/qtservice and created a service to run
npm startcommand which will start my website on Windows startup. When adding-execargument, 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_Hinsuranceservice.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.
@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
npmand app instance needs. -
@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
npmand app instance needs.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.
-
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.
-
@Cobra91151 I am not a real Node.js person. Does this help?
I already tried
node-windowsbut 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 withQThread,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. -
I already tried
node-windowsbut 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 withQThread,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.I updated the main post.
Additionally, I will create the logger to check what exectly executes in the start method.
-
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. -
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.I tried to run this service with the built-in
logMessagemethod: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 Viewerit reports: The start method executing....
But for some reason everything belowlogMessage()does not execute. The log file does not exists which should be created. It could be the issue thatlogMessage()runs on one instance andQFilecreates/runs on another instance. I need somehow to connect to the right instance. -
I tried to run this service with the built-in
logMessagemethod: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 Viewerit reports: The start method executing....
But for some reason everything belowlogMessage()does not execute. The log file does not exists which should be created. It could be the issue thatlogMessage()runs on one instance andQFilecreates/runs on another instance. I need somehow to connect to the right instance.Additionally, I created a test method in
QtServiceBaseclass.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
InsuranceServiceclass I call mymyCustomMessage()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 theQtServiceto share some details about this issue? Thanks. -
I tried to run this service with the built-in
logMessagemethod: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 Viewerit reports: The start method executing....
But for some reason everything belowlogMessage()does not execute. The log file does not exists which should be created. It could be the issue thatlogMessage()runs on one instance andQFilecreates/runs on another instance. I need somehow to connect to the right instance.@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.
-
@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.
I just run
InsuranceService.exe -execincmdand it works beause I see the file is created and data is written there as well. When I runNET START InsuranceServicecommand, the service is started and running but no file is created.Also, I add my test method to
QtServiceBaseclass 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
QFtpclass. I will try to use Qt shared build and provide all dlls components. -
I just run
InsuranceService.exe -execincmdand it works beause I see the file is created and data is written there as well. When I runNET START InsuranceServicecommand, the service is started and running but no file is created.Also, I add my test method to
QtServiceBaseclass 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
QFtpclass. I will try to use Qt shared build and provide all dlls components.@Cobra91151 I suggested what I would do.
-
@Cobra91151 I suggested what I would do.
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. -
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.It only executes theQtServiceBasemethods. 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. -
I tried to run this service with the built-in
logMessagemethod: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 Viewerit reports: The start method executing....
But for some reason everything belowlogMessage()does not execute. The log file does not exists which should be created. It could be the issue thatlogMessage()runs on one instance andQFilecreates/runs on another instance. I need somehow to connect to the right instance.@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. -
@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.I will debug it again because it seems some code is skipped when running it as a service. Thank you.
-
@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.Ok. I have properly debug the app and found out that
QProcess,QStandardPaths::writableLocationandqgetenvare 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. -
C Cobra91151 has marked this topic as solved on
-
C Cobra91151 has marked this topic as unsolved on
-
C Cobra91151 has marked this topic as solved on