Qt Service不进入事件循环问题

huangapple go评论65阅读模式
英文:

Qt Service does not enter the event loop issue

问题

我使用了旧的 QtService 代码,链接如下:https://github.com/qtproject/qt-solutions/tree/master/qtservice,并创建了一个服务来运行 npm start 命令,该命令将在 Windows 启动时启动我的网站。当添加 -exec 参数时,在应用程序模式下它能正常工作,但在服务模式下它不起作用。在调试过程中,我发现它没有正确进入服务事件循环。因此,我创建了一个小示例,用于演示这个问题并将一些文本写入 txt 文件。

代码:

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();
}

有关如何正确进入服务事件循环的任何想法吗?

更新:

我尝试使用内置的 logMessage 方法运行此服务:

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();
}

Event Viewer 中,它报告:The start method executing.... 但是由于某种原因,logMessage() 下面的一切都不会执行。应该创建的日志文件不存在。可能的问题是 logMessage() 在一个实例上运行,而 QFile 在另一个实例上创建/运行。我需要以某种方式连接到正确的实例。

谢谢。

英文:

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 &lt;QCoreApplication&gt;
#include &lt;QObject&gt;
#include &lt;QThread&gt;
#include &lt;QDebug&gt;
#include &quot;qtservice.h&quot;
#include &quot;servicelogger.h&quot;

class InsuranceService : public QtService&lt;QCoreApplication&gt;
{
    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 &amp;argc, char *argv[]);
};

#endif // INSURANCESERVICE_H

insuranceservice.cpp

#include &quot;insuranceservice.h&quot;

InsuranceService::InsuranceService(int argc, char *argv[]) : QtService&lt;QCoreApplication&gt;(argc, argv, &quot;InsuranceService&quot;)
{
    std::cout &lt;&lt; serviceName().toStdString().c_str() &lt;&lt; std::endl;
    setServiceDescription(&quot;Test service&quot;);
    setServiceFlags(QtServiceBase::CanBeSuspended);
    //setStartupType(QtServiceController::AutoStartup);
}

void InsuranceService::start()
{
    try {
        QCoreApplication *insuranceApp = application();
        QFile *logFile = new QFile(ServiceLogger::getLogPath(), insuranceApp); 
        logFile-&gt;open(QIODevice::WriteOnly | QIODevice::Append);
        ServiceLogger::writeLog(logFile, QString(&quot;Test...&quot;).toUtf8());
        logFile-&gt;close();
        logFile-&gt;deleteLater();
    } catch (...) {
        qCritical() &lt;&lt; &quot;Failed to start the service!!!&quot;;
    }
}

void InsuranceService::stop()
{

}

void InsuranceService::pause()
{

}

void InsuranceService::resume()
{

}

void InsuranceService::processCommand(int code)
{
    Q_UNUSED(code);
}

void InsuranceService::createApplication(int &amp;argc, char *argv[])
{
    QtService::createApplication(argc, argv);
}

InsuranceService::~InsuranceService()
{

}

main.cpp

#include &lt;QCoreApplication&gt;
#include &quot;insuranceservice.h&quot;

int main(int argc, char *argv[])
{
    InsuranceService service(argc, argv);
    return service.exec();
}

Any ideas how to enter the service event loop correctly?

Updated:

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

void InsuranceService::start()
{
    logMessage(&quot;The start method executing....&quot;, QtServiceBase::Success, 0, 0);
    QFile *logFile = new QFile(ServiceLogger::getLogPath());
    logFile-&gt;open(QIODevice::WriteOnly | QIODevice::Append);
    ServiceLogger::writeLog(logFile, QString(&quot;Test...&quot;).toUtf8());
    logFile-&gt;close();
    logFile-&gt;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.

Thank you.

答案1

得分: 1

我已经正确调试了应用程序,并发现在应用程序作为服务运行时,QProcessQStandardPaths::writableLocationqgetenv不起作用。看来服务功能受限。因此,我决定将我的应用程序设置为在操作系统启动时运行,而不是作为服务。现在,它运行正常。问题已解决。谢谢。

英文:

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.

huangapple
  • 本文由 发表于 2023年6月19日 21:03:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/76506920.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定