Git Product home page Git Product logo

skycoder42 / qtservice Goto Github PK

View Code? Open in Web Editor NEW
147.0 15.0 49.0 2.06 MB

A platform independent library to easily create system services and use some of their features

Home Page: https://skycoder42.github.io/QtService/

License: BSD 3-Clause "New" or "Revised" License

QMake 7.00% C++ 92.16% C 0.14% CMake 0.08% Java 0.61%
qt services systemservice systemd windows-service launchd android-service plugins terminal

qtservice's Introduction

QtService

A platform independent library to easily create system services and use some of their features

Github Actions status Codacy Badge AUR

Looking for a maintainer! If anyone is interested in continuing development of the library, please write me here: #30

Features

  • Allows you to create system (and user) services for various systems
    • Provides a single Interface to implement only once without having to care to much about the platform
    • Actual platform specifc stuff is provided via plugins, making it easy to support other backends as well
    • Most backends support native logging (i.e. journald, syslog, winevents, ...)
    • Supports socket-activation (for systemd & launchd)
    • Interfaces can be used to handle general service events
  • Easy testing/debugging by simply switching the service backend via the start arguments
  • Provides very basic service control to, e.g. get the status of a service or start/stop it
  • Provides generic callbacks to allow realtively easy access to platform specific features
  • Comes with a "Terminal frontend mode" which allows to create a CLI interface that communicates with the actual service without any extra coding needed
    • Terminals will connect to the running service. If none is running, they can start it (on some platforms)
    • Terminals send their command line arguments to the running service
    • A connected terminal can send input to the master (via stdin) and receive output (stdout)
    • Terminals can disconnect by beeing closed, leaving the service running (even the one that started the master)
    • The Service gets a "Terminal" handle for each connected terminal, allowing parallel connections. Each terminal implements QIODevice, making communication easy
    • For all this no extra code is needed from your side
  • Supported service backends:
    • Systemd (For most modern Linux Distros)
    • Windows Services
    • Launchd (Tested on MacOs, but should theoretically work on other unixes as well)
    • Android Services
    • "Standard Services" - A platform independed dummy backend that runs services as a normal proccess - useful for testing, debugging or as fallback.
  • QtCreator template to easily create a service project, with configuration file templates for each platform

Note: What this framework does explicitly not handle is "service installation" - as that is extremly different on all platforms and cannot be easily generalized. Performing the service installation, registration or whatever the platform needs is up to the developer. However, all the files that are needed as metadata for a service on each platform are provided via the QtCreator project template, which makes it significantly easier to deploy your service, as all thats left is to correctly "apply" those.

Details on what exactly is supported by each backend can be found in the doxygen documentation under the "Related Pages" tab.

Download/Installation

  1. Package Managers: The library is available via:
    • Arch-Linux: AUR-Repository: qt5-service
    • MacOs:
      • Tap: brew tap Skycoder42/qt-modules
      • Package: qtservice
      • IMPORTANT: Due to limitations of homebrew, you must run source /usr/local/opt/qtservice/bashrc.sh before you can use the module.
  2. Simply add my repository to your Qt MaintenanceTool (Image-based How-To here: Add custom repository):
    1. Start the MaintenanceTool from the commandline using /path/to/MaintenanceTool --addTempRepository <url> with one of the following urls (GUI-Method is currently broken, see QTIFW-1156) - This must be done every time you start the tool:
    2. A new entry appears under all supported Qt Versions (e.g. Qt > Qt 5.11 > Skycoder42 Qt modules)
    3. You can install either all of my modules, or select the one you need: Qt Service
    4. Continue the setup and thats it! you can now use the module for all of your installed Kits for that Qt Version
  3. Download the compiled modules from the release page. Note: You will have to add the correct ones yourself and may need to adjust some paths to fit your installation! In addition to that, you will have to download the modules this one depends on as well.
  4. Build it yourself! Note: This requires all build an runtime dependencies to be available. If you don't have/need cmake, you can ignore the related warnings. To automatically build and install into your Qt installation, run:
    1. Install and prepare qdep
    2. Download the sources. Either use git clone or download from the releases. If you choose the second option, you have to manually create a folder named .git in the projects root directory, otherwise the build will fail.
    3. qmake
    4. make (If you want the tests/examples/etc. run make all)
    5. Optional step: make doxygen to generate the documentation
    6. make install

Usage

The C++ part of the Service is relatively simple. All you have to do is implement the QtService::Service interface and start it in your main. The most important methods of the service are start and stop - which are called when the service was started or stopped...

class TestService : public QtService::Service
{
	Q_OBJECT

public:
	explicit TestService(int &argc, char **argv) : //the reference here is important!
		Service{argc, argv}
	{}

protected:
	CommandMode onStart() override {
		qDebug() << "Service was started";
		return Synchronous; //service is now assumed started
	}

	CommandMode onStop(int &exitCode) override {
		qDebug() << "Stop received";
		// do some complicated stopping stuff asynchronously that takes some time...
		QTimer::singleShot(3000, this, [this](){
			emit stopped(EXIT_SUCCESS);
		});
		return Asynchronous; // service is still stopping until "stopped" has been emitted
	}
};

int main(int argc, char *argv[]) {
	// IMPORTANT: do NOT create a QCoreApplication here - this is done internally by the backends!
	// also, do nothing else in the main besides setting the serices properties! Any setup etc. must all be
	// done in the onStart method!!!
	TestService service{argc, argv};
	return service.exec();
}

Rules of usage:
You should always follow the following rules when using/creating a service. You can also find this list in the QtService::Service class documentation:

  • Do not create a QCoreApplication yourself - this is done internally
  • Use the same constructor signature to pass the main arguments. It is very important that the argc argument is passed as reference! Passing as value will crash your application
  • Do nothing else in the main besides setting the serices properties that need to be set early! Any setup etc. must all be done in the Service::onStart method!!! (The properties that need to be set early all have a hint in their documentation)
  • Never call QCoreApplication::quit (or QCoreApplication::exit)! Use Service::quit instead
  • Do not rely on QCoreApplication::aboutToQuit, as this may not be emitted at all, or on some arbitrary point. Put all cleanup code in the Service::onStop method
  • Be careful with Service::preStart - only use it when you have no other choice

Actually running the service depends on your choosen backend. When testing with the standard backend, you can simply run the service without any parameters, or the backend explicitly specified:

/path/to/service --backend standard

To run with a system backend, you need to register the executable somehow in the service system of your operating system. The trick here is to register it with the backend as parameter. So for example, on windows you would register the service as \path\to\service --backend windows. For more details check the documentation or create a service project from the template - it will create service files that already do this for you.

Terminals

To allow terminals, you must set the QtService::Service::terminalActive property to true and implement the QtService::Service::terminalConnected and optionally the QtService::Service::verifyCommand methods. The service is started the same way as usual. Internally, you will get the terminals as soon as they have connected and can then process their arguments and communicate with them.

To start a terminal client, simply prepend --terminal as well as the backend the service is running on to the command line. It is recommended to create a small wrapper script for each platform that takes care of these parameters. On linux, for example, you would create a shell script like below that simply starts the executable with the additional parameters:

#!/bin/sh
# use as "service-cli <arguments>" (assuming this script is named service-cli)
exec /path/to/service --backend systemd --terminal "$@"

(The platform argument is recommended to not depend on any windowing system)

Service Control

The QtService::ServiceControl allows you to control services by sending commands to them and retrieving the status. However, what exactly is possible greatly varies for each platform. Always use QtService::ServiceControl::supportFlags to figure out what you can actually do on the current platform. You can also check the doxygen documentation to get an overview over all the backends and their features.

Trouble shooting

Sometimes, a service just won't start, without any apparent reason. This can be very hard to debug, as you cannot debug a service with traditional means. The best tricks I came by this problems are:

  1. Enable as much debugging as possible, by setting the QT_LOGGING_RULES environment variable to qt.service.*.debug=true. This will enable debug logging for the service internals, which might help. To access the system logs, refer to your service managers documentation.
  2. Sometimes, logs are empty or the service crashes before starting. This often indicates, that the service plugins cannot be found. In that case, make sure that:
    1. If you deployed your application, check that the servicebackends plugin folder exists and that the plugin you want to use is in there (for example, qwindows[d].dll for the windows backend).
    2. Check or generate the qt.conf file. It should contain an enty named Plugins that points to the directory that contains the servicebackends folder.
    3. If that still does not help, you can try to manually specify the plugin folder via an environment variable. Simply set QT_PLUGIN_PATH to the directory that contains the servicebackends folder. Use an absolute path if possible.

Important: Some service managers (like windows) do not allow to set environment variables for services from the outside. In such cases, you must set the variables in your main, before loading the service. For example, to set QT_PLUGIN_PATH, you would do:

int main(int argc, char **argv) {
    const auto appDir = QFileInfo{QString::fromUtf8(argv[0])}.dir();
    qputenv("QT_PLUGIN_PATH", appDir.absolutePath().toUtf8());
    
    QtService::Service service{argc, argv};
    return service.exec();
}

Documentation

The documentation is available on github pages. It was created using doxygen. The HTML-documentation and Qt-Help files are shipped together with the module for both the custom repository and the package on the release page. Please note that doxygen docs do not perfectly integrate with QtCreator/QtAssistant.

References

The Service backend code for the windows plugin was created by using the code from https://github.com/qtproject/qt-solutions as a basis.

qtservice's People

Contributors

felix-barz-brickmakers avatar sanych1by avatar skycoder42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qtservice's Issues

snapping QtService

it is possible to snap an application that use Qtservice with snapcraft?

Passing startup params

Hello! I pass custom params via sc create myservice binPath= ...
I find that args in main during debug (which is OK). But args from QCoreApplication instance contains only app name in onStart() handler. So, QtService mutates args. What is the workaround?
I always need to pass some user params during startup to child QProcess instance with onStart slot.
BTW, standard backend mode does not eat args. At least, windows backend mode mutates args.

About debugging using VS

Hello. I am using QtService to act as a HttpServer. Compile perfectly fine. When I try debug using VS 2017. I could see the logs coming out and shows that onStart() is running. But I cannot connect to the port which HttpServer opend. BTW: It is running correctly using standard QtCoreApplication way.
Here is the code:

QtService::Service::CommandResult onStart() override {
	qDebug() << Q_FUNC_INFO;
	HttpPluginServer plugins{ "routes.json" };
	HttpServer server;
	HttpServerRequestRouter router{
		{ QRegularExpression{""}, HttpFileServer::handler("public")},
		{ QRegularExpression{""}, NotFoundHandler::handler()}
	};

	QObject::connect(&server, &HttpServer::requestReady,
		&router, &HttpServerRequestRouter::handleRequest);

	server.listen(QHostAddress::Any, 8080);
	qDebug() << server.isListening(); // returns true
	qDebug() << "Service was started";
	return Synchronous; //service is now assumed started
}

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

Thx so much.

Looking for a new maintainer

I am currently not working with Qt anymore and do not have the time to maintain the project. If someone is interested in taking over the library, please write me here.

qmake Cannot find feature qdep

I need to build this service.
but there are problems at the qmake stage

andrei@HP-Laptop-15:~/gitHub/QtService$ ~/Qt/5.13.2/gcc_64/bin/qmake -r 
Reading /home/andrei/gitHub/QtService/src/src.pro
 Reading /home/andrei/gitHub/QtService/src/service/service.pro
Project MESSAGE: perl -w /home/andrei/Qt/5.13.2/gcc_64/bin/syncqt.pl -module QtService -version 2.0.2 -outdir /home/andrei/gitHub/QtService -builddir /home/andrei/gitHub/QtService /home/andrei/gitHub/QtService
<srcbase> = /home/andrei/gitHub/QtService 
<bldbase> = /home/andrei/gitHub/QtService 
<outbase> = /home/andrei/gitHub/QtService 
/home/andrei/gitHub/QtService/src/service/service.pro:45: Cannot find feature qdep
Project ERROR: Failed to load qdep feature! Run 'qdep prfgen --qmake /home/andrei/Qt/5.13.2/gcc_64/bin/qmake' to create it.

I need detailed instructions or a way to build this service from source and without installing additional components.

P.S.
Thank you for your project, a very interesting job.)

c++17 -> c++11

hi,

In order to make it works easily on old Linux version, I would prefer that the lib can compile with c++11. Is that possible, or am I missing something ?

WindowsServiceBackend can't start.

Sometimes Windows can't start a backend service, the status is always Starting.
There are logs at that time.

qt.service.plugin.windows.backend: waiting for control thread...
qt.service.plugin.windows.backend: entered control thread
qt.service.plugin.windows.backend: registering service
qt.service.plugin.windows.backend: passing start arguments to main thread
qt.service.plugin.windows.backend: setting status to start pending
qt.service.backend: Running pre start service routine
qt.service.plugin.windows.backend: continuing control thread
qt.service.plugin.windows.backend: running application
qt.service.plugin.windows.backend: wait for main thread to finish startup 

And compare with a normal log.

qt.service.plugin.windows.backend: waiting for control thread...
qt.service.plugin.windows.backend: entered control thread
qt.service.plugin.windows.backend: registering service
qt.service.plugin.windows.backend: passing start arguments to main thread
qt.service.plugin.windows.backend: wait for main thread to finish startup
qt.service.plugin.windows.backend: setting status to start pending
qt.service.backend: Running pre start service routine
qt.service.plugin.windows.backend: continuing control thread
qt.service.plugin.windows.backend: running application
qt.service.plugin.windows.backend: handle service start event

Maybe the control thread is deadlock because the below line in function WindowsServiceBackend::serviceMain
_backendInstance->_startCondition.wait(&_backendInstance->_svcLock);

I tried a simple test to reproduce.
I see when runService of main thread is completed before serviceMain of control thread, a same issue is occurred.

#ifndef WORKERS_H
#define WORKERS_H
#include <QThread>
#include <QDebug>
#include <QWaitCondition>
#include <QMutexLocker>
#include <QMutex>
#include <QCoreApplication>

static QMutex _svcLock;
static QWaitCondition _startCondition;

class SvcControlThread : public QThread {
public:
    void run() {
        qDebug() << "entered control thread";
        qDebug() << "registering service";
        qDebug() << "passing start arguments to main thread";
        QMutexLocker lock(&_svcLock);
        _startCondition.wakeAll();
        lock.unlock();

        QThread::sleep(10);
        // wait for the mainthread to finish startup, then register the service handler
        lock.relock();
        qDebug() << "wait for main thread to finish startup";
        qDebug() << _startCondition.wait(&_svcLock);
        lock.unlock();

        // handle the start event
        qDebug() << "handle service start event";
    }
};

class WindowsServiceBackend {
public:
    void runService(int &argc, char **argv) {
        SvcControlThread controlThread;
        qDebug() << "waiting for control thread...";
        controlThread.start(QThread::LowestPriority);
        QMutexLocker lock(&_svcLock);
        if(!_startCondition.wait(&_svcLock, 20000))
            return;
        lock.unlock();
        qDebug() << "setting status to start pending";
        QCoreApplication app(argc, argv);

        lock.relock();
        qDebug() << "continuing control thread";
        _startCondition.wakeAll();
        lock.unlock();

        //execute the app
        qDebug() << "running application";
        app.exec();

    }
};

#endif // WORKERS_H
#include <QCoreApplication>
#include <Workers.h>

int main(int argc, char *argv[])
{
    WindowsServiceBackend wsb;
    wsb.runService(argc, argv);
}

Security policies

Hello. I am experimenting with QtService in Linux Mint. Please, consider the following error message:
hwmon_system_service[306]: qtservice.servicebackends.systemd: org.freedesktop.DBus.Error.AccessDenied: Connection ":1.159" is not allowed to own the service "hwmon_system_service.systemd-service" due to security policies in the configuration file.

How this error can be fixed?

Impossible to build on Ubuntu 16.04

  1. Cloning sources
  2. qmake && make:
    ...
    .../QtService/src/service/service.pro:45: Cannot find feature qdep
    Project ERROR: Failed to load qdep feature! Run 'qdep prfgen --qmake /usr/lib/x86_64-linux-gnu/qt5/bin/qmake' to create it.
    ...
    make: *** [sub-src-make_first] Error 2
  3. qdep prfgen --qmake /usr/lib/x86_64-linux-gnu/qt5/bin/qmake
    Traceback (most recent call last):
    File "/usr/local/bin/qdep", line 10, in
    sys.exit(main())
    File "/usr/local/lib/python3.5/dist-packages/qdep/internal/cli.py", line 163, in main
    prfgen(path.abspath(sys.argv[0]), res.qmake, res.dir)
    File "/usr/local/lib/python3.5/dist-packages/qdep/qdep.py", line 12, in prfgen
    qmake_res = sub_run([qmake, "-query", "QT_HOST_DATA"], check=True, stdout=subprocess.PIPE, encoding="UTF-8")
    File "/usr/local/lib/python3.5/dist-packages/qdep/internal/common.py", line 59, in sub_run
    return subprocess.run(*args, **kwargs)
    File "/usr/lib/python3.5/subprocess.py", line 693, in run
    with Popen(*popenargs, **kwargs) as process:
    TypeError: init() got an unexpected keyword argument 'encoding'

I need to make a service use qt console application

There are a few questions.The environment is Centos7

1.I tyied use qt creator ,new qt console application,Create a new project TEST,create TEST.service,Then start it with this command.
systemctl start TEST.service。
It can run normally.why? Qtservice Function?

2.Qtservice Can you provide a simple QT creator project? Just print the log.Or loop out UDP messages.Just need to be able to start it with a command.

systemctl start *.service

I've tried many times.It just won't start it with a command.
Please forgive me, I may not know much about this.

Thanks a lot.

Question about how you define androidextras

Update: This issue only appears if using Qt Online Installer, I am on Arch Linux Manjaro, once I uninstalled it, I did a full Qt pacman install and rebooted, this issue went away.

Note I had another issue with the Qt Online Installer having a different compiler signature, and I did try to uninstall and reinstall, and checked permissions, but the Offical Repos work fine, and no issues like this.

I am not developing for Android currently, but my computer is set up for it, my interest in this project is to see if I can use it for QtHttpServer, which is currently a QtLabs project slated for Qt, but I am having a hard time getting started with the example for the EchoService, this is not related to my issue, but it stops me from compiling the project since I do not have androidextras installed on my Desktop, but I could on my Android device, if you get my meaning, I get a lot of warnings, but I only get them for two of the three projects, and I think its due to the way you define them in QT += androidextras, for example:

In service.pro
android: QT += androidextras
In android.pro
QT += service androidextras
In AndroidServiceTest.pro
QT += quick service androidextras

If I change them as such the compile error and warnings go away:

In android.pro
QT               += service
android: QT += androidextras

In AndroidServiceTest.pro
QT              += quick service
android: QT += androidextras

Maybe you can look at this, this fix got rid of all the warnings, and now it compiles without errors, the logic is clear enough, only an Android device can use androidextras, so I am sure my fix is correct.

Thanks, Flesh

QTService with QProcess

Hi. I am trying touse QTService as my service solution and have to call other python script during service running. I have tested it and works well on normal mode without --backend windows. But when I install it as a windows services, the QTService main process is running well but python script didn't work any more. Any comments on that?
Thx a lot.

WindowsServiceBackend doesn't work with the Unicode characters in the path

WindowsServiceBackend works fine when the path of the executable file contains only the latin characters, but it won't be able to find plugins when the path contains the non-latin characters. I can fix it as below code. But I'm not sure if this issue affect other parts of QtService or not.

Replace these lines

    const auto appDir = QFileInfo{QString::fromUtf8(argv[0])}.dir();
    qputenv("QT_PLUGIN_PATH", appDir.absolutePath().toUtf8());

To

    LPWSTR *szArglist;
    int nArgs;
    szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
    if( NULL == szArglist )
    {
       qCritical() << "CommandLineToArgvW failed";
       return 0;
    }
    const auto appDir = QFileInfo{QString::fromWCharArray(szArglist[0])}.dir();
    std::wstring path = appDir.absolutePath().toStdWString();
    _wputenv_s(L"QT_PLUGIN_PATH", path.c_str());

Can't set a dbus object path - fixed value

In the systemd implementation there is a hard-coded dbus object path:

const QString SystemdServiceBackend::DBusObjectPath = QStringLiteral("/de/skycoder42/QtService/SystemdServiceBackend");

I can't see any way to change this. Can this be changed into a property so I can override/set it?

Example EchoControl ask for a Name, what does it refer to?

I have had several issues, and not sure if this is still more, I have the echoservice running from a terminal, using ./echoservice , it comes up Service running with backend: "standard", Started echo server on port 36985, so when I run EchoControl, I was thinking the name would be echoservice, or even echoservice.service, then I tired the port number, after that its just a guessing game, but it could not find it, can you explain how it should work, please.

I am trying to write a simple QtHttpServer instanced, and want to start, stop, pause, resume, reload, the normal things, and I need the stop, pause, and was wondering if you had any example that might help, I have searched the internet, and cannot find much. I ask because I saw you have an example of it in your Repo, which I am checking out.

Thanks, and sorry about the two issues, other than that the Qt Online installation seemed to work fine, that bash file pointed the finger at Qt, but I was using the Arch Linux AUR version, and it too was different, so it was confusing me, I tried reinstalling, no help, removing it and installing the Official Qt version from the Arch Linux Manjaro Repo fixed everything, except this issue, I think its a user error if you ask me since I have no idea what the name should be.

Cutelyst as a system service

Hello! I am studying C++/Qt REST framework Cutelyst. I'd like to make cutelyst-wsgi2 (see cutelyst-wsgi2 sources) as a system service.
In fact, I'd like to have a a crossplatform (Win/Linux) ability to start/stop REST service, autorestart it in case of crashes. REST service will be used in local network, I'd like to avoid Apache and other reverse proxies.
What will you advise? For example, is it reasonable to make a thin system service based on QtService that will in turn start cutelyst-wsgi2? I suppose that in-source mixing cutelyst-wsgi2 and QtService will be hard according to main.cpp contents. For example, cutelyst-wsgi2 has own calls to QCoreApplication::exec(). Also, I don't want to fork multiple cutelyst-wsgi2 processes (so, I choose only a restricted subset of cutelyst-wsgi2 features - multithreaded, but single process).
BTW, what's the difference between https://github.com/qtproject/qt-solutions/tree/master/qtservice and your project?

Example EchoControl on exit has error undefined symbol: _ZdlPvm, version Qt_5

Update: Running Arch Linux Manjaro, after troubleshooting this more, I found out that it was caused by the Qt Online Installer version, installing it with pacman, and a reboot, and recompile and it started working, I have not found this fix anywhere on the Internet, but this is a strange error, and I could not figure out why Qt was compiled with a different compiler version, and it turns out to be the Online installer.

I wrote a bash file to see what the deal is, and as usual, its a problem with compiling with different versions of a compiler between Qt and the stdc++ library.

/usr/lib/libQt5Core.so.5 >> U _ZdlPvm /usr/lib/libstdc++.so.6 >> 00000000000a1ca0 T _ZdlPvm00000000000a3c30 T _ZdlPvmSt11align_val_t

This is the script you can test it yourself, the QtCore is compiled with a different version of gcc, so the signatures do not match.

#!/bin/bash
# Written by Jeffrey Scott Flesher
# Last update 21 May 2020
# This script is used to help find Library Programs
# undefined symbol: _ZdlPvm, version Qt_5
# given an Executalbe is will show you all the results, look for ones that differ.
#
# "${HOME}/findLibProblem.sh" EchoControl
#
if [ $# -ne 1 ]; then echo "Pass Executable name in as argument"; fi
findIssues()
{
    OIFS=$IFS;
    IFS=' => ';
    # Skip the first line
    for item in "${@:2}"; do 
        # only look at paths
        if [[ $item = /* ]]; then
            #myValue="$(nm --with-symbol-versions -D "$item" | grep _ZdlPvm;)";
            myValue="$(nm -D "$item" | grep _ZdlPvm;)";
            if [ -n "$myValue" ]; then
                myValue="${myValue//[$'\t\r\n']}";
                myValue="$(echo -e "${myValue}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')";     
                echo "$item >> $myValue";
            fi
        fi
    done
    IFS=$OIFS;
}
declare MyLdd="$(ldd $1)";
findIssues $MyLdd;
# End of File 

I tried a few things to fix it with no solution

linux: {
    # undefined symbol: _ZdlPvm, version Qt_5
    QMAKE_CXXFLAGS   *= "-fno-sized-deallocation"
    #CONFIG          *= "c++11"
    #CONFIG          *= "c++14"
    CONFIG           *= "c++latest"
    INCLUDEPATH      *= /usr/include/qt
    INCLUDEPATH      *= /usr/include/qt/QtService
    LIBS             *= -L"/usr/lib"
    LIBS             *= -L"/usr/lib64"
    # suppress the default RPATH if you wish but it did not help
    # QMAKE_LFLAGS_RPATH=
    # add your own with quoting gyrations to make sure $ORIGIN gets to the command line unexpanded
    QMAKE_LFLAGS *= "-Wl,-rpath,\'\$$ORIGIN\'"
}

I am running Arch Linux Manajaro, with latest updates.

My guess is that I need to compile Qt and or the stdc++ library to sync them, any ideas?

Thanks, Flesh

How can I implement enable and disable in the Echo Example

Update: I set up an example project here https://github.com/Light-Wizzard/EchoReloadedService

What all do I need to implement, this is what I have so far if its even close, I was hoping you had an example that showed how to implement ServiceControl, what I was going to try is this:

# Header of Echo Server
#include <QtService/ServiceControl>
CommandResult onEnable();
CommandResult onDisable();
QtService::ServiceControl *myServerControl = nullptr;

# Echo Server cpp
EchoReloadedService::EchoReloadedService(int &argc, char **argv) : Service(argc, argv), myServerControl(nullptr)
{
    myServerControl->setParent(this);
}
QtService::Service::CommandResult EchoService:: onEnable()
{
    qDebug() << Q_FUNC_INFO;
    if (!myServerControl->isAutostartEnabled())
    {
        myServerControl->enableAutostart();
    }
    return CommandResult::Completed;
}
QtService::Service::CommandResult EchoService:: onDisable()
{
    qDebug() << Q_FUNC_INFO;
    if (myServerControl->isAutostartEnabled())
    {
        myServerControl->disableAutostart();
    }
    return CommandResult::Completed;
}

What I am trying to accomplish is simple, I want to create a Travis and AppVeyor installation app for a modified version of Echo Server and Controller, and I want the ability to use the enable/disable feature, and I am pretty sure in Unix its just a link that gets created and deleted, in Windows its a registry change, and my guess is that is what these functions do, but not so sure how to use them.

My goal here is to create an App the End Users can Fork or copy, which allows them to install and test this example, in a real-world application, so the Qt Installer Framework Installer will install the Echo Server, and the Echo Controller, fill filling the Name with the Default installation path and name, so the end-user only needs to hit the load button, I can enable the service in the installers script file.

This is all part of that Tututural I am working on, and where I am stuck at, I want to show the whole process for using QtService, from development to deployment, so it really needs this feature to be complete.

I need a way to connect this to arguments passed in to Qt main, passed through into QtServer, not sure how you do that yet, such that it takes --enable and --disable for --backend systemd diable and --backend systemd enable, how is this accomplished?

Its normal for me to get lost in new projects, and ask a lot of questions, and even mix stuff between them different projects you might have, and even in your case, the other project for a similar project for Windows exists, so it gets confusing, not sure why, PTSD, TBI, or just old age (60ish), but what really got my curiosity is your QtHttpServer Repo, having been a long time Wt, Cute user, I am wondering if they will include this ability, if so, what are your thoughts?

I have read your comments about Cute, if he has integrated it, I have no clue where to start looking, I did revisit his site today and I did not get deep into it for a few reasons, so I never finished my project with them, and why is simple, I could not find a nice way to ensure the client was not cut off, and I tried using HaProxy, in hope of keeping the old server up long enough for them to finish, thinking on a new request I would give them an updated server, but on a reboot, that just did not work out, and why I needed to find a better solution, and I am hoping to find out if QtHttpServer will provide this support, but even if it does, I still need my own implementation of it, to pull this off.

If I remember right, both Apache and NGINX use a thin c wrapper around script, that actually just kills the pid, and why I could never get my app to work with either, and why I say if I remember right, its been a while, and things might have changed, but last I looked, it did not have the ability to negotiate with clients, for example, I need to reboot, so I want to send out a command to all Clients to go into an offline mode in so many seconds, or auto offline will kick in automatically unless you want to reschedule this now, and wait for time out, then if no reply, make all online clients offline, and after reboot, mark them online again, so this is also a feature that Echo Server should have.

What I want to do is write an expanded version of Echo, maybe change the name, and start a new project, so this does not get confusing, I Forked QtServer, so to keep it simple, we can call it "Echo Reloaded" since that is the main feature I am adding, the ability to ask the Client if its ok to reload, or reboot the server, and even add a scheduler, that can push cron events in Unix, and Scheduled Task in Windows, so it can be a useful example, even a template for other apps to be based on.

WeBookServer will use this app for its template, so I need the ability to run QtHttpServer, so I can use this feature, to control it, and that is what the tutorial there is all about.

WeBookClient needs to connect to WeBookServer, and since it cannot connect like Echo Client, and really I only want the Admin to have the ability to reload or reboot the server, and I still want to use a Qt c++ app, as such, my WeBookClient needs to talk directly to WeBookServer, and negotiate and verify AES encrypted traffic, so that the Client can Authenticate with the Server, without the need or use of User Name and Password, the reason why should be self-evident, if you follow my train of thought, and out of High School I was an Air Brake Machanic on Trains, so this is a long train ride, and we have a lot of clients to serve, so I want to be able to control access to only clients that were built using my Travis or AppVeyor account, so I can verify the checksum or some metadata I can compile into it, using a backside Environment variable for security, to ensure the Client and Server are both writen and compiled by the same GitHub/Travis/AppVeyor account, if you are following this train, you see the trail of Trust, now SSL is fine, but that comes at a cost, as does using GitHub/Travis/AppVeyor Private accounts, but SSL has issues, and User Name and Password is just Crazy, now SSH is one option is you can get it to work using a key, that is another train of thought, but easy enought to test, I have a VPS account that is keyed, but end users need more options, not everyone can get a VPS account with a keyed access, so I am looking for options that have SSL and User Name/Password, as the last option, if you know what I mean.

I will finish as much as possible, the Tutorials for WeBookServer and WeBookClient, but the Client is not like Echo Controller, the concept is that your first option is a VPS account, you create a key, and key it the first time you log in, this will be in the Tutorial, still need to verify this works, before moving on to the next option, which gets more limiting as you go along.

Now my question is this, can I, meaning should I, connect with the TCP server like Echo Controller, and this gets back to if you can do this over a keyed ssh connection, or the next type of authentication level that works. The end goal is easy, I use Qt-AES for Encryption, I could have picked an approved method, but did not need it the way I implement this, as such, only the Server and Client know the keys, or have the keys, and without them, the communication is just gibberish, so I do not really need SSL, my method uses a random authentication method, so it does not repeat the same authentication twice, preventing the middle man attacks, and you could enhance this with SSL even if its self-signed, so you need to test all your options and make them features. Most of the Tutorial for WeBook is already started, but I needed a better foundation to start with for the Server.

WeBook itself is a Qt c++ Rich Text Editor that saves to HTML, it manages it like a Web-Book, and making that one-word as in webbook, did not work for me, it manages it like a book, with chapters, and sub-chapters, and the Server just routes it to its destination, with Navigation built-in, so the end-user controls the web site via the Tree View it creates, so QtHttpServer is a match for what it needs to do out of the box, and all the app does is manage the books, contacts, calendar, and files, for collaboration via the WeBookClient, as such, they form a Domain Controller Group and have a Central Login Manager built-in, and it manages SSH keys, it can generate them, issue them, verify them, and revoke them.

I want to make WeBookClient have both Admin abilities to log into and control their own Domain, but also the ability to join others as just a Client.

WeBook also handles file synchronization, and chat, text, video, as well as file exchange, with all collaborators, so it also needs to run clamscan and maldetect on all these types of communications, so I need a way to communicate with the Server as an Admin, so I can manage this account, using this software, so the tutorial is going to be broken down into sections to cover all the aspects of it, but I imagine I can push the boundaries of what it can do.

That is the road-map this train is going away, one step at a time, with tones of questions in between, joking, I hope to keep it to as few as possible, I just wanted to give you enough details to understand where this Tutorial is going and ask you if Echo example will work with the modifications I need, or if there is a better road to take.

I have not posted any code for WeBookServer yet, but I am working on the Wiki:

https://github.com/Light-Wizzard/WeBookServer/wiki/System.d

Thanks for any help, Flesh

SystemdAdaptor missing

Hi,

first of all thank you for your project!
I try to compile systemd plugin with cmake but it fails because
"systemd_adaptor.h" and "systemd_interface.h" can not be found.
Where did you get these files from?

Thx in advance

QCoreApplication::instance() returns a null in application.

I have been encountering a problem when testing servicebackend on Windows.
I built the QtService project independently by the same Kit used for my project then copy the libs and plugin to my project.

My problem is after built and loaded the servicebackends plugin then create and run my service successfully (i can see the status of service is running and got logs). but checking QCoreApplication object, I see QCoreApplication object that plugin created isn't the object that i get in my project when using the function static QCoreApplication::instance(), on my project it always is null. so my project can't use event loop.

Any comments on that?
Thanks you.

A dead project that depends on another dead project

Hi,

I only wasted my time just now to find out how exactly do you plan to offer this project for people (since you are replying to issues) when it depends on https://github.com/Skycoder42/qdep which is marked as "read only" and you explicitly stated inside issues that you do not want to maintain it anymore.

Aside from that, it is clear that a sheer amount of work has been input into this and the other library, including the documentation. I can say kudos on that, but... they are impossible to use.

Thanks,

All the best

QtService with QT6

I used QtService with Qt5 on Mac Intel.
Qt official support for Mac ARM start with version 6.x.
Do you support Qt6 ?

Learn QTService from Scratch

Hii!! How Can I make services for windows using QT C++ programming, I want to learn qtservice from the scratch, Can anyone helpme in this ? Share me a reference or documentary where I learn QT service step by step.

qmake error build QtService

Following steps to build QtService on a Windows 10 system with Visual Studio 2022/2019 and Qt 5.15.11:

  • qdep installed using pip install qdep

  • qdep prfgen --qmake "C:\Qt\5.15.11\msvc2019_64\bin\qmake.exe"
    Generating PRF-File as: C:/Qt/5.15.11/msvc2019_64\mkspecs\features\qdep.prf

  • set PATH=C:\Qt\5.15.11\msvc2019_64\bin;%PATH%

  • git clone https://github.com/Skycoder42/QtService.git

  • mkdir buildQtService && cd buildQtService

  • qmake ..\buildQtService -r
    results in the following error:
    Info: creating stash file C:\Users\<USER>\source\repos\buildQtService\.qmake.stash Info: creating cache file C:\Users\<USER>\source\repos\buildQtService\.qmake.cache Reading C:/Users/<USER>/source/repos/QtService/src/src.pro [C:/Users/<USER>/source/repos/buildQtService/src] Reading C:/Users/<USER>/source/repos/QtService/src/service/service.pro [C:/Users/<USER>/source/repos/buildQtService/src/service] Project MESSAGE: perl -w C:\Qt\5.15.11\msvc2019_64\bin\syncqt.pl -module QtService -version 2.0.2 -outdir C:/Users/<USER>/source/repos/buildQtService -builddir C:/Users/<USER>/source/repos/buildQtService C:/Users/<USER>/source/repos/QtService <srcbase> = C:/Users/<USER>/source/repos/QtService <bldbase> = C:/Users/<USER>/source/repos/buildQtService <outbase> = C:/Users/<USER>/source/repos/buildQtService QtService: created fwd-include header(s) for <srcbase>/src/service/ { qtservice_global.h (1), qtservice_helpertypes.h (1), service.h (2), service_p.h (1), servicebackend.h (2), servicebackend_p.h (1), servicecontrol.h (2), servicecontrol_p.h (1), serviceplugin.h (2), terminal.h (2), terminal_p.h (1), terminalclient_p.h (1), terminalserver_p.h (1) } QtService: created version header QtService: created master header QtService: created headers.pri file 'C:\Program' is not recognized as an internal or external command, operable program or batch file. Project ERROR: qdep.py script version () is different to qdep.prf version (1.1.1)! Run 'C:\Program Files\Anaconda3\Scripts\qdep.exe prfgen --qmake C:/Qt/5.15.11/msvc2019_64/bin/qmake.exe' to update the prf file!

I need information on what could be causing the error. I have followed the instructions, but without success.

@Skycoder42 Thank you for the project. So far I used a very old (from Qt4 times) version of QtService and wanted to switch to something more recent for a new project ;0)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.