├── .gitignore
├── PluginManager
├── .gitignore
├── MyPluginOne
│ ├── MyPluginOne.json
│ ├── MyPluginOne.pro
│ ├── mypluginone.cpp
│ ├── mypluginone.h
│ └── mypluginone_global.h
├── PM.pri
├── PM.pro
├── PluginManager
│ ├── PluginManager.pro
│ └── main.cpp
└── README.txt
├── TestLaunchBrowser
├── TestLaunchBrowser.pro
├── main.cpp
├── mainwindow.cpp
├── mainwindow.h
└── mainwindow.ui
├── TestLoadDependencies
├── TestLoadDependencies.pro
├── dependencyList.txt
└── main.cpp
├── TestQMutexQThread
├── TestQMutexQThread.pro
├── main.cpp
├── worker.cpp
└── worker.h
├── TestQSystemSemaphore
├── MyExe
│ ├── MyExe.pro
│ └── main.cpp
├── TestMyExeWithQSystemSemaphore
│ ├── TestMyExeWithQSystemSemaphore.pro
│ └── main.cpp
└── TestQSystemSemaphore.pro
├── TestSignalTrigger
├── PluginOne
│ ├── PluginOne.h
│ ├── PluginOne.json
│ ├── PluginOne.pro
│ ├── pluginone.cpp
│ └── pluginone_global.h
├── PluginTwo
│ ├── PluginTwo.json
│ ├── PluginTwo.pro
│ ├── plugintwo.cpp
│ ├── plugintwo.h
│ └── plugintwo_global.h
├── README.txt
├── TestPluginOnePluginTwo
│ ├── TestPluginOnePluginTwo.pro
│ └── main.cpp
├── TestQtService
│ ├── TestQtService.pro
│ ├── TestQtService.pro.user
│ ├── main.cpp
│ ├── message_handler.cpp
│ ├── message_handler.h
│ ├── mydaemon.cpp
│ ├── mydaemon.h
│ ├── myservice.cpp
│ ├── myservice.h
│ ├── process_loader.cpp
│ ├── process_loader.h
│ └── qtservice
│ │ ├── INSTALL.TXT
│ │ ├── README.TXT
│ │ ├── buildlib
│ │ └── buildlib.pro
│ │ ├── common.pri
│ │ ├── configure
│ │ ├── configure.bat
│ │ ├── doc
│ │ ├── html
│ │ │ ├── classic.css
│ │ │ ├── images
│ │ │ │ └── qt-logo.png
│ │ │ ├── index.html
│ │ │ ├── qtservice-example-controller.html
│ │ │ ├── qtservice-example-interactive.html
│ │ │ ├── qtservice-example-server.html
│ │ │ ├── qtservice-members.html
│ │ │ ├── qtservice.dcf
│ │ │ ├── qtservice.html
│ │ │ ├── qtservice.index
│ │ │ ├── qtservice.qhp
│ │ │ ├── qtservicebase-members.html
│ │ │ ├── qtservicebase.html
│ │ │ ├── qtservicecontroller-members.html
│ │ │ └── qtservicecontroller.html
│ │ ├── images
│ │ │ └── qt-logo.png
│ │ └── index.qdoc
│ │ ├── qtservice.pro
│ │ ├── qtservice.pro.user
│ │ └── src
│ │ ├── QtService
│ │ ├── QtServiceBase
│ │ ├── QtServiceController
│ │ ├── qtservice.cpp
│ │ ├── qtservice.h
│ │ ├── qtservice.pri
│ │ ├── qtservice_p.h
│ │ ├── qtservice_unix.cpp
│ │ ├── qtservice_win.cpp
│ │ ├── qtunixserversocket.cpp
│ │ ├── qtunixserversocket.h
│ │ ├── qtunixsocket.cpp
│ │ └── qtunixsocket.h
├── TestSignalTrigger.pri
└── TestSignalTrigger.pro
├── TestWindowsService
├── .gitignore
├── README.txt
├── TestWindowsService.pri
├── TestWindowsService.pro
├── main.cpp
├── message_handler.cpp
├── message_handler.h
├── my_windows_service.cpp
├── my_windows_service.h
├── qt-service-lib
│ ├── debug
│ │ ├── QtSolutions_Service-headd.dll
│ │ ├── QtSolutions_Service-headd.lib
│ │ └── qtsolutions_service-headd.pdb
│ ├── include
│ │ └── qtservice.h
│ └── release
│ │ ├── QtSolutions_Service-head.dll
│ │ └── QtSolutions_Service-head.lib
├── windowassist.cpp
└── windowassist.h
└── TestWindowsServiceWithLibrarySource
├── TestWindowsServiceWithLibrarySource.pri
├── TestWindowsServiceWithLibrarySource.pro
├── main.cpp
├── my_windows_service.cpp
├── my_windows_service.h
└── qtservice
├── qtservice.cpp
├── qtservice.h
├── qtservice.pri
├── qtservice_p.h
├── qtservice_unix.cpp
├── qtservice_win.cpp
├── qtunixserversocket.cpp
├── qtunixserversocket.h
├── qtunixsocket.cpp
└── qtunixsocket.h
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pro.user
2 | build/
3 | build-*
4 |
--------------------------------------------------------------------------------
/PluginManager/.gitignore:
--------------------------------------------------------------------------------
1 | *.user
2 |
--------------------------------------------------------------------------------
/PluginManager/MyPluginOne/MyPluginOne.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FinixLei/QtProjects/8092222c35a70ca37d8f9a99f91cf925ffa8253c/PluginManager/MyPluginOne/MyPluginOne.json
--------------------------------------------------------------------------------
/PluginManager/MyPluginOne/MyPluginOne.pro:
--------------------------------------------------------------------------------
1 | include(../PM.pri)
2 |
3 | QT -= gui
4 |
5 | TARGET = MyPluginOne
6 | TEMPLATE = lib
7 |
8 | DEFINES += MYPLUGINONE_LIBRARY
9 |
10 | SOURCES += mypluginone.cpp
11 |
12 | HEADERS += mypluginone.h\
13 | mypluginone_global.h
14 |
15 | unix {
16 | target.path = /usr/lib
17 | INSTALLS += target
18 | }
19 |
--------------------------------------------------------------------------------
/PluginManager/MyPluginOne/mypluginone.cpp:
--------------------------------------------------------------------------------
1 | #include "mypluginone.h"
2 |
3 |
4 | MyPluginOne::MyPluginOne(int data, QString name)
5 | : data(data)
6 | , dataName(name)
7 | {
8 | }
9 |
10 | MyPluginOne::~MyPluginOne()
11 | {}
12 |
13 | void MyPluginOne::setData(int data)
14 | {
15 | this->data = data;
16 | emit dataChanged(data);
17 | }
18 |
19 | void MyPluginOne::setDataName(QString name)
20 | {
21 | dataName = name;
22 | emit dataNameChanged(name);
23 | }
24 |
25 | int MyPluginOne::getData()
26 | {
27 | return data;
28 | }
29 |
30 | QString MyPluginOne::getDataName()
31 | {
32 | return dataName;
33 | }
34 |
--------------------------------------------------------------------------------
/PluginManager/MyPluginOne/mypluginone.h:
--------------------------------------------------------------------------------
1 | #ifndef MYPLUGINONE_H
2 | #define MYPLUGINONE_H
3 |
4 | #include "mypluginone_global.h"
5 |
6 | #include
7 |
8 | class MYPLUGINONESHARED_EXPORT MyPluginOne : public QObject
9 | {
10 | Q_OBJECT
11 | Q_PLUGIN_METADATA(IID "mypluginone" FILE "MyPluginOne.json")
12 |
13 | public:
14 | MyPluginOne(int data=-1, QString name="InitialName");
15 | ~MyPluginOne();
16 |
17 | public slots:
18 | void setData(int data);
19 | void setDataName(QString name);
20 |
21 | public:
22 | int getData();
23 | QString getDataName();
24 |
25 | signals:
26 | void dataChanged(int data);
27 | void dataNameChanged(QString name);
28 |
29 | private:
30 | int data;
31 | QString dataName;
32 | };
33 |
34 | Q_DECLARE_METATYPE(MyPluginOne*)
35 |
36 | #endif // MYPLUGINONE_H
37 |
--------------------------------------------------------------------------------
/PluginManager/MyPluginOne/mypluginone_global.h:
--------------------------------------------------------------------------------
1 | #ifndef MYPLUGINONE_GLOBAL_H
2 | #define MYPLUGINONE_GLOBAL_H
3 |
4 | #include
5 |
6 | #if defined(MYPLUGINONE_LIBRARY)
7 | # define MYPLUGINONESHARED_EXPORT Q_DECL_EXPORT
8 | #else
9 | # define MYPLUGINONESHARED_EXPORT Q_DECL_IMPORT
10 | #endif
11 |
12 | #endif // MYPLUGINONE_GLOBAL_H
13 |
--------------------------------------------------------------------------------
/PluginManager/PM.pri:
--------------------------------------------------------------------------------
1 | CONFIG(debug, debug|release) {
2 | DR_CONFIG_NAME = debug
3 | } else {
4 | DR_CONFIG_NAME = release
5 | }
6 |
7 | DESTDIR = $$PWD/../build/$$DR_CONFIG_NAME
8 |
9 | LIBS += -L$$DESTDIR
10 |
--------------------------------------------------------------------------------
/PluginManager/PM.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = subdirs
2 |
3 | SUBDIRS += \
4 | MyPluginOne \
5 | PluginManager
6 |
7 | PluginManager.depends = \
8 | MyPluginOne
9 |
--------------------------------------------------------------------------------
/PluginManager/PluginManager/PluginManager.pro:
--------------------------------------------------------------------------------
1 | include(../PM.pri)
2 |
3 | QT += core
4 | QT -= gui
5 |
6 | CONFIG += c++11
7 |
8 | TARGET = PluginManager
9 | CONFIG += console
10 | CONFIG -= app_bundle
11 |
12 | TEMPLATE = app
13 |
14 | SOURCES += main.cpp
15 |
16 | INCLUDEPATH += $$PWD/../MyPluginOne
17 |
18 | LIBS += -lMyPluginOne
19 |
--------------------------------------------------------------------------------
/PluginManager/PluginManager/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "MyPluginOne.h"
8 |
9 | QObject* retrievePackage(const QString& pkgName)
10 | {
11 | QString name = pkgName.toLower();
12 |
13 | QFile file(name);
14 | QPluginLoader loader(file.fileName());
15 |
16 | if (!loader.load())
17 | {
18 | qDebug() << "Failed to load " << name << "........";
19 | }
20 |
21 | QObject* packageObj = loader.instance();
22 | return packageObj;
23 | }
24 |
25 |
26 | int main(int argc, char *argv[])
27 | {
28 | QCoreApplication a(argc, argv);
29 |
30 | QObject* pkgObj = retrievePackage("MyPluginOne");
31 | MyPluginOne* mpo = qobject_cast(pkgObj);
32 |
33 | QObject::connect(mpo, &MyPluginOne::dataChanged,
34 | [](int data){
35 | qDebug() << "Get dataChanged() Notification! It is " << data;
36 | });
37 | QObject::connect(mpo, &MyPluginOne::dataNameChanged,
38 | [](QString name){
39 | qDebug() << "Get dataNameChanged() Notification! It is " << name;
40 | });
41 |
42 | if (mpo)
43 | {
44 | mpo->setData(100);
45 | qInfo() << "Data = " << mpo->getData();
46 | mpo->setDataName("GoodBoy");
47 | qInfo() << "Name = " << mpo->getDataName();
48 | }
49 | else
50 | {
51 | qDebug() << "Failed to do qobject_cast";
52 | }
53 |
54 | return a.exec();
55 | }
56 |
--------------------------------------------------------------------------------
/PluginManager/README.txt:
--------------------------------------------------------------------------------
1 | A very simple project to test QtPlugin, loading QtPlugin and connect signal after loading QtPlugin.
--------------------------------------------------------------------------------
/TestLaunchBrowser/TestLaunchBrowser.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2016-04-27T14:55:54
4 | #
5 | #-------------------------------------------------
6 |
7 | QT += core gui
8 |
9 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
10 |
11 | TARGET = TestBrowser2
12 | TEMPLATE = app
13 |
14 |
15 | SOURCES += main.cpp\
16 | mainwindow.cpp
17 |
18 | HEADERS += mainwindow.h
19 |
20 | FORMS += mainwindow.ui
21 |
--------------------------------------------------------------------------------
/TestLaunchBrowser/main.cpp:
--------------------------------------------------------------------------------
1 | #include "mainwindow.h"
2 | #include
3 |
4 | int main(int argc, char *argv[])
5 | {
6 | QApplication a(argc, argv);
7 | MainWindow w;
8 | w.show();
9 |
10 | return a.exec();
11 | }
12 |
--------------------------------------------------------------------------------
/TestLaunchBrowser/mainwindow.cpp:
--------------------------------------------------------------------------------
1 | #include "mainwindow.h"
2 | #include "ui_mainwindow.h"
3 |
4 | #include
5 | #include
6 |
7 | MainWindow::MainWindow(QWidget *parent) :
8 | QMainWindow(parent),
9 | ui(new Ui::MainWindow)
10 | {
11 | ui->setupUi(this);
12 | }
13 |
14 | MainWindow::~MainWindow()
15 | {
16 | delete ui;
17 | }
18 |
19 | void MainWindow::on_pushButton_clicked()
20 | {
21 | QDesktopServices::openUrl(QUrl("http://www.bing.com"));
22 | }
23 |
--------------------------------------------------------------------------------
/TestLaunchBrowser/mainwindow.h:
--------------------------------------------------------------------------------
1 | #ifndef MAINWINDOW_H
2 | #define MAINWINDOW_H
3 |
4 | #include
5 |
6 | namespace Ui {
7 | class MainWindow;
8 | }
9 |
10 | class MainWindow : public QMainWindow
11 | {
12 | Q_OBJECT
13 |
14 | public:
15 | explicit MainWindow(QWidget *parent = 0);
16 | ~MainWindow();
17 |
18 | private slots:
19 | void on_pushButton_clicked();
20 |
21 | private:
22 | Ui::MainWindow *ui;
23 | };
24 |
25 | #endif // MAINWINDOW_H
26 |
--------------------------------------------------------------------------------
/TestLaunchBrowser/mainwindow.ui:
--------------------------------------------------------------------------------
1 |
2 |
3 | MainWindow
4 |
5 |
6 |
7 | 0
8 | 0
9 | 400
10 | 300
11 |
12 |
13 |
14 | MainWindow
15 |
16 |
17 |
18 |
19 |
20 | 170
21 | 100
22 | 91
23 | 41
24 |
25 |
26 |
27 | Bing
28 |
29 |
30 |
31 |
41 |
42 |
43 | TopToolBarArea
44 |
45 |
46 | false
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/TestLoadDependencies/TestLoadDependencies.pro:
--------------------------------------------------------------------------------
1 | QT += core
2 | QT -= gui
3 |
4 | CONFIG += c++11
5 |
6 | TARGET = TestLoadDependencies
7 | CONFIG += console
8 | CONFIG -= app_bundle
9 |
10 | TEMPLATE = app
11 |
12 | SOURCES += main.cpp
13 |
--------------------------------------------------------------------------------
/TestLoadDependencies/dependencyList.txt:
--------------------------------------------------------------------------------
1 | # This is a comment line.
2 |
3 | C:/Users/Finix/AppData/Local/Fortis/bin/proapi_touchmat-0.2.3/win32-msvc2013-x64-d/touchmat2.dll
4 |
5 | C:\\Users\\Finix\\AppData\\Local\\Fortis\\bin\\proapi_hal-0.2.3\\win32-msvc2013-x64-d\\hal.dll
6 |
7 | C:/Users/Finix/AppData/Local/Fortis/bin/proapi_leds-0.2.3/win32-msvc2013-x64-d/leds.dll
8 |
9 | C:\\Users\\Finix\\AppData\\Local\\Fortis\\bin\\proapi_hal-0.2.3\\win32-msvc2013-x64-d\\hal.dll
10 |
11 | C:/Users/Finix/AppData/Local/Fortis/bin/proapi_touchmat-0.2.3/win32-msvc2013-x64-d/touchmat.dll
12 |
--------------------------------------------------------------------------------
/TestLoadDependencies/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | void readDependencyConfigFile(const QString& filePath, QVector& vec)
11 | {
12 | QFile file(filePath);
13 | if(!file.open(QIODevice::ReadOnly | QIODevice::Text))
14 | {
15 | qCritical() << "Warning: Cannot open " << filePath;
16 | }
17 |
18 | QTextStream in(&file);
19 | QString line;
20 | while(in.readLineInto(&line))
21 | {
22 | vec.push_back(line);
23 | }
24 |
25 | file.close();
26 | }
27 |
28 |
29 | bool goodLibPath(const QString& libPath)
30 | {
31 | bool result = true;
32 |
33 | if (libPath.size() == 0) {
34 | result = false;
35 | }
36 | else if (libPath.at(0) == '#') {
37 | result = false;
38 | }
39 | else {
40 | QFile file(libPath);
41 | if (!file.exists())
42 | {
43 | qDebug() << "The file does not exists: " << libPath;
44 | result = false;
45 | }
46 | }
47 |
48 | return result;
49 | }
50 |
51 |
52 | // Load the library as a QtPlugin
53 | QObject* loadQtPlugin(const QString& libPath)
54 | {
55 | QPluginLoader loader(libPath);
56 |
57 | if (!loader.load())
58 | {
59 | qCritical() << "Failed to load " << libPath << ".....................";
60 | }
61 |
62 | QObject* libObj = loader.instance();
63 | return libObj;
64 | }
65 |
66 |
67 | // Load all the libraries as QtPlugin
68 | void loadLibrariesAsQtPlugin(const QString& configFile)
69 | {
70 | QVector libraryList;
71 | readDependencyConfigFile(configFile, libraryList);
72 |
73 | for(int i=0; i>>>>>>>>> " << "Loading " << libPath << "............";
80 | QObject* lib = loadQtPlugin(libPath);
81 | if (!lib)
82 | {
83 | qCritical() << "Failed to load: " << libPath;
84 | }
85 | }
86 | else
87 | {
88 | qCritical() << "Ignore the line: " << libPath;
89 | }
90 | qDebug() << "";
91 | }
92 | }
93 |
94 |
95 | void loadLibraries(const QString& configFile)
96 | {
97 | QVector libraryList;
98 | readDependencyConfigFile(configFile, libraryList);
99 |
100 | for(int i=0; i>>>>>>>> " << "Loading QtPlugin: " << libPath << ".............";
112 | loadQtPlugin(libPath);
113 | }
114 | else
115 | {
116 | qDebug() << ">>>>>>>>>> " << "Loading normal library: " << libPath << "............";
117 | QLibrary lib(libPath);
118 | if (!lib.load())
119 | {
120 | qCritical() << "Failed to load: " << libPath;
121 | }
122 | }
123 |
124 | qDebug() << "";
125 | }
126 | }
127 | }
128 |
129 | QString getEnvVar(const QString& envVar)
130 | {
131 | QString value(qgetenv(envVar.toStdString().c_str()));
132 |
133 | if (value == "") {
134 | qCritical() << "No such environment variable: " << envVar;
135 | } else {
136 | qDebug() << "The value of environment variable " << envVar << " is " << value;
137 | }
138 |
139 | return value;
140 | }
141 |
142 | int main(int argc, char *argv[])
143 | {
144 | QCoreApplication a(argc, argv);
145 |
146 | QString configFile = "C:/Users/Finix/Desktop/dependencyList.txt";
147 |
148 | // loadLibrariesAsQtPlugin(configFile);
149 | loadLibraries(configFile);
150 |
151 | return 0;
152 | }
153 |
--------------------------------------------------------------------------------
/TestQMutexQThread/TestQMutexQThread.pro:
--------------------------------------------------------------------------------
1 | QT += core
2 | QT -= gui
3 |
4 | CONFIG += c++11
5 |
6 | TARGET = TestQSemaphore
7 | CONFIG += console
8 | CONFIG -= app_bundle
9 |
10 | TEMPLATE = app
11 |
12 | SOURCES += main.cpp \
13 | worker.cpp
14 |
15 | HEADERS += \
16 | worker.h
17 |
--------------------------------------------------------------------------------
/TestQMutexQThread/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "worker.h"
5 |
6 |
7 | int main(int argc, char *argv[])
8 | {
9 | QCoreApplication a(argc, argv);
10 |
11 | QThread* t1 = new QThread;
12 | QThread* t2 = new QThread;
13 |
14 | Worker* w1 = new Worker;
15 | Worker* w2 = new Worker;
16 |
17 | w1->moveToThread(t1);
18 | w2->moveToThread(t2);
19 |
20 | QObject::connect(t1, &QThread::started, w1, &Worker::run);
21 | QObject::connect(w1, &Worker::finished, t1, &QThread::quit);
22 | QObject::connect(w1, &Worker::finished, [](){qInfo() << "w1 quit......";});
23 | QObject::connect(w1, &Worker::finished, w1, &Worker::deleteLater);
24 | QObject::connect(t1, &QThread::finished, t1, &QThread::deleteLater);
25 |
26 | QObject::connect(t2, &QThread::started, w2, &Worker::run);
27 | QObject::connect(w2, &Worker::finished, t2, &QThread::quit);
28 | QObject::connect(w2, &Worker::finished, [](){qInfo() << "w2 quit......";});
29 | QObject::connect(w2, &Worker::finished, w2, &Worker::deleteLater);
30 | QObject::connect(t2, &QThread::finished, t2, &QThread::deleteLater);
31 |
32 |
33 | t1->start();
34 | t2->start();
35 |
36 | t1->wait(300);
37 | t2->wait(300);
38 |
39 | qInfo() << "At the end of main thread...";
40 |
41 | return 0;
42 | }
43 |
--------------------------------------------------------------------------------
/TestQMutexQThread/worker.cpp:
--------------------------------------------------------------------------------
1 | #include "worker.h"
2 | #include
3 |
4 |
5 | int Worker::myValue = 0;
6 | QMutex Worker::leds_mutex;
7 |
8 | Worker::Worker(QObject* parent)
9 | : QObject(parent)
10 | , m_id(QUuid::createUuid().toString())
11 | {
12 | }
13 |
14 | Worker::~Worker()
15 | {
16 | }
17 |
18 | void Worker::run()
19 | {
20 | int count = 0;
21 | while (count < 5) {
22 | ++count;
23 | Worker::leds_mutex.lock();
24 |
25 | QFile file;
26 | QDir::setCurrent("C:/Users/Finix/Desktop");
27 | file.setFileName("1.txt");
28 | if (!file.open(QIODevice::Append | QIODevice::Text)) {
29 | qCritical() << "Failed to open file";
30 | Worker::leds_mutex.unlock();
31 | break;
32 | }
33 |
34 | QTextStream out(&file);
35 | out << "id: " << m_id << ", myValue = " << Worker::myValue << '\n';
36 | qInfo() << "id: " << m_id << ", myValue = " << Worker::myValue;
37 | ++Worker::myValue;
38 |
39 | Worker::leds_mutex.unlock();
40 | }
41 |
42 | emit finished();
43 | }
44 |
--------------------------------------------------------------------------------
/TestQMutexQThread/worker.h:
--------------------------------------------------------------------------------
1 | #ifndef MYTHREAD_H
2 | #define MYTHREAD_H
3 |
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 |
11 | class Worker : public QObject
12 | {
13 | Q_OBJECT
14 |
15 | private:
16 | static int myValue;
17 | static QMutex leds_mutex;
18 | QString m_id;
19 |
20 | public:
21 | Worker(QObject* parent = nullptr);
22 | ~Worker();
23 |
24 | public slots:
25 | void run();
26 |
27 | signals:
28 | void finished();
29 | void error(QString err);
30 | };
31 |
32 | #endif // MYTHREAD_H
33 |
--------------------------------------------------------------------------------
/TestQSystemSemaphore/MyExe/MyExe.pro:
--------------------------------------------------------------------------------
1 | QT += core
2 | QT -= gui
3 |
4 | CONFIG += c++11
5 |
6 | TARGET = MyExe
7 | CONFIG += console
8 | CONFIG -= app_bundle
9 |
10 | TEMPLATE = app
11 |
12 | SOURCES += main.cpp
13 |
14 | DESTDIR = $$PWD/../build
15 |
--------------------------------------------------------------------------------
/TestQSystemSemaphore/MyExe/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | int main(int argc, char *argv[])
11 | {
12 | QCoreApplication a(argc, argv);
13 |
14 | QUuid uuid = QUuid::createUuid();
15 | QString id = uuid.toString();
16 |
17 | QSystemSemaphore qss("MySystemSemaphore", 1);
18 |
19 | int count = 0;
20 | while (count < 5) {
21 | ++count;
22 | qss.acquire();
23 |
24 | QFile file;
25 | QDir::setCurrent("C:/Users/Finix/Desktop");
26 | file.setFileName("out.txt");
27 | if (!file.open(QIODevice::Append | QIODevice::Text)) {
28 | qDebug() << "Failed to open file";
29 | qss.release();
30 | break;
31 | }
32 |
33 | QTextStream out(&file);
34 | out << id << ": " << count << "\n";
35 | qDebug() << id << ": " << count;
36 | QThread::sleep(1);
37 | qss.release();
38 | }
39 |
40 | qDebug() << "Exit...";
41 |
42 | return 0;
43 | }
44 |
--------------------------------------------------------------------------------
/TestQSystemSemaphore/TestMyExeWithQSystemSemaphore/TestMyExeWithQSystemSemaphore.pro:
--------------------------------------------------------------------------------
1 | QT += core
2 | QT -= gui
3 |
4 | CONFIG += c++11
5 |
6 | TARGET = MyExeTest
7 | CONFIG += console
8 | CONFIG -= app_bundle
9 |
10 | TEMPLATE = app
11 |
12 | SOURCES += main.cpp
13 |
14 | DESTDIR = $$PWD/../build
15 |
--------------------------------------------------------------------------------
/TestQSystemSemaphore/TestMyExeWithQSystemSemaphore/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | QCoreApplication a(argc, argv);
8 |
9 | std::thread t1([](){QProcess::execute("./MyExe.exe");});
10 | std::thread t2([](){QProcess::execute("./MyExe.exe");});
11 |
12 | t1.join();
13 | t2.join();
14 |
15 | return 0;
16 | }
17 |
--------------------------------------------------------------------------------
/TestQSystemSemaphore/TestQSystemSemaphore.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = subdirs
2 |
3 | SUBDIRS += \
4 | MyExe \
5 | TestMyExeWithQSystemSemaphore
6 |
7 | TestMyExeWithQSystemSemaphore.depends = MyExe
8 |
--------------------------------------------------------------------------------
/TestSignalTrigger/PluginOne/PluginOne.h:
--------------------------------------------------------------------------------
1 | #ifndef PLUGINONE_H
2 | #define PLUGINONE_H
3 |
4 | #include
5 | #include "pluginone_global.h"
6 |
7 | class PLUGINONESHARED_EXPORT PluginOne : public QObject
8 | {
9 | Q_OBJECT
10 | Q_PLUGIN_METADATA(IID "pluginone" FILE "PluginOne.json")
11 |
12 | public:
13 | PluginOne(int d = 0);
14 | ~PluginOne();
15 |
16 | Q_INVOKABLE int getData();
17 |
18 | public slots:
19 | void setData(int x);
20 |
21 | signals:
22 | void dataChanged(int x);
23 |
24 |
25 | private:
26 | int data;
27 | };
28 |
29 | Q_DECLARE_METATYPE(PluginOne*)
30 |
31 | #endif // PLUGINONE_H
32 |
--------------------------------------------------------------------------------
/TestSignalTrigger/PluginOne/PluginOne.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FinixLei/QtProjects/8092222c35a70ca37d8f9a99f91cf925ffa8253c/TestSignalTrigger/PluginOne/PluginOne.json
--------------------------------------------------------------------------------
/TestSignalTrigger/PluginOne/PluginOne.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2016-04-14T15:41:09
4 | #
5 | #-------------------------------------------------
6 |
7 | include(../TestSignalTrigger.pri)
8 |
9 | QT -= gui
10 |
11 | TARGET = PluginOne
12 | TEMPLATE = lib
13 |
14 | DEFINES += PLUGINONE_LIBRARY
15 |
16 | SOURCES += pluginone.cpp
17 |
18 | HEADERS += pluginone.h\
19 | pluginone_global.h
20 |
21 | unix {
22 | target.path = /usr/lib
23 | INSTALLS += target
24 | }
25 |
--------------------------------------------------------------------------------
/TestSignalTrigger/PluginOne/pluginone.cpp:
--------------------------------------------------------------------------------
1 | #include "pluginone.h"
2 |
3 |
4 | PluginOne::PluginOne(int d) : data(d)
5 | {
6 | }
7 |
8 | PluginOne::~PluginOne()
9 | {
10 | }
11 |
12 | int PluginOne::getData() {
13 | return data;
14 | }
15 |
16 | void PluginOne::setData(int x) {
17 | data = x;
18 | emit dataChanged(x);
19 | }
20 |
--------------------------------------------------------------------------------
/TestSignalTrigger/PluginOne/pluginone_global.h:
--------------------------------------------------------------------------------
1 | #ifndef PLUGINONE_GLOBAL_H
2 | #define PLUGINONE_GLOBAL_H
3 |
4 | #include
5 |
6 | #if defined(PLUGINONE_LIBRARY)
7 | # define PLUGINONESHARED_EXPORT Q_DECL_EXPORT
8 | #else
9 | # define PLUGINONESHARED_EXPORT Q_DECL_IMPORT
10 | #endif
11 |
12 | #endif // PLUGINONE_GLOBAL_H
13 |
--------------------------------------------------------------------------------
/TestSignalTrigger/PluginTwo/PluginTwo.json:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FinixLei/QtProjects/8092222c35a70ca37d8f9a99f91cf925ffa8253c/TestSignalTrigger/PluginTwo/PluginTwo.json
--------------------------------------------------------------------------------
/TestSignalTrigger/PluginTwo/PluginTwo.pro:
--------------------------------------------------------------------------------
1 | #-------------------------------------------------
2 | #
3 | # Project created by QtCreator 2016-04-14T15:50:26
4 | #
5 | #-------------------------------------------------
6 |
7 | include(../TestSignalTrigger.pri)
8 |
9 | QT -= gui
10 |
11 | TARGET = PluginTwo
12 | TEMPLATE = lib
13 |
14 | DEFINES += PLUGINTWO_LIBRARY
15 |
16 | SOURCES += plugintwo.cpp
17 |
18 | HEADERS += plugintwo.h\
19 | plugintwo_global.h
20 |
21 | unix {
22 | target.path = /usr/lib
23 | INSTALLS += target
24 | }
25 |
--------------------------------------------------------------------------------
/TestSignalTrigger/PluginTwo/plugintwo.cpp:
--------------------------------------------------------------------------------
1 | #include "plugintwo.h"
2 |
3 | #include
4 |
5 |
6 | PluginTwo::PluginTwo(const QString name)
7 | : fileName(name), destFile(name)
8 | {
9 | destFile.resize(0);
10 | }
11 |
12 | PluginTwo::~PluginTwo()
13 | {
14 | }
15 |
16 | void PluginTwo::writeFile(int x)
17 | {
18 | qDebug() << "writeFile() slot is triggered " << x;
19 |
20 | if (destFile.open(QFile::WriteOnly | QFile::Append)) {
21 | QTextStream out(&destFile);
22 | out << "Result: " << left << x << "\t" << x << "\n";
23 | }
24 |
25 | destFile.close();
26 | }
27 |
--------------------------------------------------------------------------------
/TestSignalTrigger/PluginTwo/plugintwo.h:
--------------------------------------------------------------------------------
1 | #ifndef PLUGINTWO_H
2 | #define PLUGINTWO_H
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #include "plugintwo_global.h"
9 |
10 | class PLUGINTWOSHARED_EXPORT PluginTwo : public QObject
11 | {
12 | Q_OBJECT
13 | Q_PLUGIN_METADATA(IID "plugintwo" FILE "PluginTwo.json")
14 |
15 | public:
16 | PluginTwo(const QString name = "PluginTwoFile.txt");
17 | ~PluginTwo();
18 |
19 | public slots:
20 | void writeFile(int x);
21 |
22 | private:
23 | QFile destFile;
24 | QString fileName;
25 | };
26 |
27 | #endif // PLUGINTWO_H
28 |
--------------------------------------------------------------------------------
/TestSignalTrigger/PluginTwo/plugintwo_global.h:
--------------------------------------------------------------------------------
1 | #ifndef PLUGINTWO_GLOBAL_H
2 | #define PLUGINTWO_GLOBAL_H
3 |
4 | #include
5 |
6 | #if defined(PLUGINTWO_LIBRARY)
7 | # define PLUGINTWOSHARED_EXPORT Q_DECL_EXPORT
8 | #else
9 | # define PLUGINTWOSHARED_EXPORT Q_DECL_IMPORT
10 | #endif
11 |
12 | #endif // PLUGINTWO_GLOBAL_H
13 |
--------------------------------------------------------------------------------
/TestSignalTrigger/README.txt:
--------------------------------------------------------------------------------
1 | In TestQtService, a Windows service can be installed, uninstalled, start, paused, or stopped.
2 | In this service, PluginOne's signal is connected to PluginTwo's slot.
3 |
4 | How to handle the service?
5 | -i install
6 | -u uninstal
7 | -s start
8 | -t stop/terminate
9 | -p pause
10 | -h help
11 |
12 | In the folder "qtservice", we use the 3rd party library/source qtsolution/qtservice.
13 | You can refer to qtsolution here: https://github.com/qtproject/qt-solutions
14 |
15 | Log is at C:\Windows\System32\MyService.log
16 |
17 | -----------------------------
18 |
19 | Note:
20 | Since Windows Vista, Windows Service does not support start a GUI application. Actually, the application has been started, and you can find it in TaskManager, but you cannot see its GUI. That's just because its GUI and the service are in session 0 where GUI cannot be seen. See the articles below for more details.
21 | http://stackoverflow.com/questions/5063731/is-there-any-way-to-start-a-gui-application-from-a-windows-service-on-windows-7
22 | https://msdn.microsoft.com/en-us/library/windows/desktop/ms683502(v=vs.85).aspx
23 |
24 | However, in the practice, Windows Service actually is able to start an application with GUI, e.g. notepad.exe. Please refer to launchGUIApplication() in mydaemon.cpp.
25 |
26 | This article also contains interesting points: http://blog.csdn.net/nirendao/article/details/51194003
27 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestPluginOnePluginTwo/TestPluginOnePluginTwo.pro:
--------------------------------------------------------------------------------
1 | include(../TestSignalTrigger.pri)
2 |
3 | QT += core
4 | QT -= gui
5 |
6 | CONFIG += c++11
7 |
8 | TARGET = TestPluginOnePluginTwo
9 | CONFIG += console
10 | CONFIG -= app_bundle
11 |
12 | INCLUDEPATH += \
13 | $$PWD/../PluginOne \
14 | $$PWD/../PluginTwo
15 |
16 | LIBS += \
17 | -L$$DESTDIR \
18 | -lPluginOne \
19 | -lPluginTwo
20 |
21 | TEMPLATE = app
22 |
23 | SOURCES += main.cpp
24 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestPluginOnePluginTwo/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "PluginOne.h"
5 | #include "PluginTwo.h"
6 |
7 | int main(int argc, char *argv[])
8 | {
9 | QCoreApplication a(argc, argv);
10 |
11 | PluginOne one(10);
12 | PluginTwo two;
13 | QObject::connect(&one, &PluginOne::dataChanged, &two, &PluginTwo::writeFile);
14 |
15 | int i = 100;
16 | while (i++ < 105) {
17 | one.setData(i);
18 | }
19 |
20 | return a.exec();
21 | }
22 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/TestQtService.pro:
--------------------------------------------------------------------------------
1 | include(../TestSignalTrigger.pri)
2 |
3 | QT += core network
4 | QT -= gui
5 |
6 | TARGET = TestQtService
7 | TEMPLATE = app
8 |
9 | CONFIG += c++11
10 | CONFIG += console
11 | CONFIG -= app_bundle
12 |
13 | DEFINES += _UNICODE
14 |
15 |
16 | INCLUDEPATH += \
17 | $$PWD/../PluginOne \
18 | $$PWD/../PluginTwo
19 |
20 | LIBS += \
21 | -L$$DESTDIR \
22 | -lPluginOne \
23 | -lPluginTwo \
24 | -lWtsApi32 \
25 | -lAdvApi32 \
26 | -lUserEnv
27 |
28 | SOURCES += main.cpp \
29 | mydaemon.cpp \
30 | myservice.cpp \
31 | message_handler.cpp \
32 | process_loader.cpp
33 |
34 | include(qtservice/src/qtservice.pri)
35 |
36 | HEADERS += \
37 | mydaemon.h \
38 | myservice.h \
39 | message_handler.h \
40 | process_loader.h
41 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #include "PluginOne.h"
14 | #include "PluginTwo.h"
15 |
16 | #include "qtservice.h"
17 | #include "myservice.h"
18 | #include "message_handler.h"
19 |
20 |
21 | int main(int argc, char **argv)
22 | {
23 | #ifdef Q_OS_WIN
24 | MessageHandler::setLogFile("C:/MyService.log");
25 | #endif
26 | qInstallMessageHandler(MessageHandler::FormatMessage);
27 |
28 | #if !defined(Q_OS_WIN)
29 | // QtService stores service settings in SystemScope, which normally require root privileges.
30 | // To allow testing this example as non-root, we change the directory of the SystemScope settings file.
31 | QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, QDir::tempPath());
32 | qWarning("(Example uses dummy settings file: %s/QtSoftware.conf)", QDir::tempPath().toLatin1().constData());
33 | #endif
34 |
35 | MyService service(argc, argv);
36 | return service.exec();
37 | }
38 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/message_handler.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "message_handler.h"
8 |
9 |
10 | QString MessageHandler::s_log = "C:/MyService.log";
11 |
12 | void MessageHandler::setLogFile(QString file)
13 | {
14 | s_log = file;
15 | }
16 |
17 | void MessageHandler::FormatMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
18 | {
19 | static QMutex mutex;
20 | mutex.lock();
21 |
22 | QFile logFile(MessageHandler::s_log);
23 | logFile.open(QIODevice::WriteOnly | QIODevice::Append);
24 |
25 | QString log("");
26 | log += QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz") + QString(" ");
27 |
28 | switch(type)
29 | {
30 | case QtDebugMsg:
31 | log += QString("[Debug]");
32 | break;
33 |
34 | case QtInfoMsg:
35 | log += QString("[Info]");
36 | break;
37 |
38 | case QtWarningMsg:
39 | log += QString("[Warn]");
40 | break;
41 |
42 | case QtCriticalMsg:
43 | log += QString("[Critical]");
44 | break;
45 |
46 | case QtFatalMsg:
47 | log += QString("[Fatal]");
48 | abort();
49 | break;
50 |
51 | default:
52 | log += QString("[UnknownLogType]");
53 | break;
54 | };
55 |
56 | log += QString(context.file)
57 | + QString(", Line ")
58 | + QString::number(context.line)
59 | + QString(": %1\n").arg(msg);
60 |
61 | QTextStream text_stream(&logFile);
62 | text_stream << log;
63 | logFile.flush();
64 | logFile.close();
65 |
66 | mutex.unlock();
67 | }
68 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/message_handler.h:
--------------------------------------------------------------------------------
1 | #ifndef MESSAGEHANDLER_H
2 | #define MESSAGEHANDLER_H
3 |
4 | #include
5 |
6 | class MessageHandler
7 | {
8 | private:
9 | MessageHandler();
10 | ~MessageHandler();
11 |
12 | public:
13 | static void setLogFile(QString file = "SproutMonitorService.log");
14 | static void FormatMessage(QtMsgType type , const QMessageLogContext &context , const QString &msg);
15 |
16 | private:
17 | static QString s_log;
18 | };
19 |
20 | #endif // MESSAGEHANDLER_HPP
21 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/mydaemon.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "mydaemon.h"
5 | #include "process_loader.h"
6 |
7 |
8 | MyDaemon::MyDaemon()
9 | {
10 | m_one = new PluginOne;
11 | m_two = new PluginTwo;
12 |
13 | QObject::connect(m_one, &PluginOne::dataChanged, m_two, &PluginTwo::writeFile);
14 | QObject::connect(m_one, &PluginOne::dataChanged, this, &MyDaemon::startProcess);
15 | }
16 |
17 | MyDaemon::~MyDaemon(){}
18 |
19 | void MyDaemon::run() {
20 | qDebug() << "Starting......";
21 | int i = 100;
22 | while (i++ < 103) {
23 | m_one->setData(i);
24 | }
25 | }
26 |
27 | void MyDaemon::pause() {
28 | qDebug() << "Paused......";
29 | }
30 |
31 | void MyDaemon::resume() {
32 | qDebug() << "Resuming......";
33 | }
34 |
35 | void MyDaemon::startProcess() {
36 | qDebug() << "Start Process......";
37 |
38 | /*
39 | QStringList parameters;
40 | parameters << "1.txt";
41 |
42 | // Do not use "system()" or "QProcess::execute()" or "QProcess.start()"
43 | // This is because they will suspend the execution of the service.
44 | QProcess::startDetached("notepad.exe", parameters);
45 | */
46 |
47 | #ifdef Q_OS_WIN
48 | std::wstring command = L"notepad.exe";
49 | if (ProcessLoader::loadWindowsApplication(command) == false) {
50 | qDebug() << "Failed to launch " << command.c_str();
51 | }
52 | #endif
53 | }
54 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/mydaemon.h:
--------------------------------------------------------------------------------
1 | #ifndef MYDAEMON_H
2 | #define MYDAEMON_H
3 |
4 | #include
5 | #include "PluginOne.h"
6 | #include "PluginTwo.h"
7 |
8 | class MyDaemon : public QObject
9 | {
10 | Q_OBJECT
11 | public:
12 | MyDaemon();
13 | ~MyDaemon();
14 |
15 | void run();
16 | void pause();
17 | void resume();
18 |
19 | void startProcess();
20 |
21 | private:
22 | PluginOne* m_one;
23 | PluginTwo* m_two;
24 | };
25 |
26 | #endif // MYDAEMON_H
27 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/myservice.cpp:
--------------------------------------------------------------------------------
1 | #include "myservice.h"
2 | #include
3 |
4 | MyService::MyService(int argc, char **argv)
5 | : QtService(argc, argv, "FinixTestDaemon")
6 | {
7 | setServiceDescription("A dummy service");
8 | setServiceFlags(QtServiceBase::CanBeSuspended);
9 | }
10 |
11 | void MyService::start()
12 | {
13 | QCoreApplication* app = application();
14 | Q_UNUSED(app);
15 |
16 | daemon = new MyDaemon();
17 |
18 | try {
19 | daemon->run();
20 | }
21 | catch(...){
22 | qDebug() << "MyDaemon exit!!!";
23 | app->quit();
24 | }
25 | }
26 |
27 | void MyService::pause() {
28 | daemon->pause();
29 | }
30 |
31 | void MyService::resume() {
32 | daemon->resume();
33 | }
34 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/myservice.h:
--------------------------------------------------------------------------------
1 | #ifndef MYSERVICE_H
2 | #define MYSERVICE_H
3 |
4 | #include "qtservice.h"
5 | #include "mydaemon.h"
6 |
7 | class MyService : public QtService
8 | {
9 | public:
10 | MyService(int argc, char **argv);
11 |
12 | protected:
13 | void start();
14 | void pause();
15 | void resume();
16 |
17 | private:
18 | MyDaemon* daemon;
19 | };
20 |
21 | #endif // MYSERVICE_H
22 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/process_loader.cpp:
--------------------------------------------------------------------------------
1 | #include "process_loader.h"
2 |
3 | #ifdef Q_OS_WIN
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | #endif
12 |
13 |
14 | ProcessLoader::ProcessLoader()
15 | {}
16 |
17 | ProcessLoader::~ProcessLoader()
18 | {}
19 |
20 |
21 | #ifdef Q_OS_WIN
22 |
23 | bool ProcessLoader::loadWindowsApplication(std::wstring command)
24 | {
25 | BOOL bResult = FALSE;
26 |
27 | DWORD dwSessionId = WTSGetActiveConsoleSessionId();
28 | if (dwSessionId == 0xFFFFFFFF)
29 | {
30 | return false;
31 | }
32 |
33 | HANDLE hUserToken = NULL;
34 | if (WTSQueryUserToken(dwSessionId, &hUserToken) == FALSE)
35 | {
36 | return false;
37 | }
38 |
39 | HANDLE hTheToken = NULL;
40 | if (DuplicateTokenEx(hUserToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &hTheToken) == TRUE)
41 | {
42 |
43 | if (ImpersonateLoggedOnUser(hTheToken) == TRUE)
44 | {
45 | DWORD dwCreationFlags = HIGH_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
46 |
47 | STARTUPINFO si = { sizeof(si) };
48 | PROCESS_INFORMATION pi;
49 | SECURITY_ATTRIBUTES Security1 = { sizeof(Security1) };
50 | SECURITY_ATTRIBUTES Security2 = { sizeof(Security2) };
51 |
52 | LPVOID pEnv = NULL;
53 | if (CreateEnvironmentBlock(&pEnv, hTheToken, TRUE) == TRUE)
54 | {
55 | dwCreationFlags |= CREATE_UNICODE_ENVIRONMENT;
56 | }
57 |
58 | TCHAR commandLine[MAX_PATH];
59 | _tcscpy_s(commandLine, MAX_PATH, command.c_str());
60 |
61 | // Launch the process in the client's logon session.
62 | bResult = CreateProcessAsUser(
63 | hTheToken,
64 | NULL, // (LPWSTR)(path),
65 | (LPWSTR)(commandLine),
66 | &Security1,
67 | &Security2,
68 | FALSE,
69 | dwCreationFlags,
70 | pEnv,
71 | NULL,
72 | &si,
73 | &pi
74 | );
75 |
76 | RevertToSelf();
77 |
78 | if (pEnv)
79 | {
80 | DestroyEnvironmentBlock(pEnv);
81 | }
82 | }
83 | CloseHandle(hTheToken);
84 | }
85 | CloseHandle(hUserToken);
86 |
87 | return bResult==TRUE;
88 | }
89 |
90 | #endif
91 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/process_loader.h:
--------------------------------------------------------------------------------
1 | #ifndef PROCESSLOADER_H
2 | #define PROCESSLOADER_H
3 |
4 | #include
5 |
6 |
7 | class ProcessLoader
8 | {
9 | public:
10 | ProcessLoader();
11 | ~ProcessLoader();
12 |
13 | public:
14 |
15 | #ifdef Q_OS_WIN
16 | static bool loadWindowsApplication(std::wstring command);
17 | #endif
18 |
19 | };
20 |
21 | #endif // PROCESSLOADER_H
22 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/INSTALL.TXT:
--------------------------------------------------------------------------------
1 | INSTALLATION INSTRUCTIONS
2 |
3 | These instructions refer to the package you are installing as
4 | some-package.tar.gz or some-package.zip. The .zip file is intended for use
5 | on Windows.
6 |
7 | The directory you choose for the installation will be referred to as
8 | your-install-dir.
9 |
10 | Note to Qt Visual Studio Integration users: In the instructions below,
11 | instead of building from command line with nmake, you can use the menu
12 | command 'Qt->Open Solution from .pro file' on the .pro files in the
13 | example and plugin directories, and then build from within Visual
14 | Studio.
15 |
16 | Unpacking and installation
17 | --------------------------
18 |
19 | 1. Unpacking the archive (if you have not done so already).
20 |
21 | On Unix and Mac OS X (in a terminal window):
22 |
23 | cd your-install-dir
24 | gunzip some-package.tar.gz
25 | tar xvf some-package.tar
26 |
27 | This creates the subdirectory some-package containing the files.
28 |
29 | On Windows:
30 |
31 | Unpack the .zip archive by right-clicking it in explorer and
32 | choosing "Extract All...". If your version of Windows does not
33 | have zip support, you can use the infozip tools available
34 | from www.info-zip.org.
35 |
36 | If you are using the infozip tools (in a command prompt window):
37 | cd your-install-dir
38 | unzip some-package.zip
39 |
40 | 2. Configuring the package.
41 |
42 | The configure script is called "configure" on unix/mac and
43 | "configure.bat" on Windows. It should be run from a command line
44 | after cd'ing to the package directory.
45 |
46 | You can choose whether you want to use the component by including
47 | its source code directly into your project, or build the component
48 | as a dynamic shared library (DLL) that is loaded into the
49 | application at run-time. The latter may be preferable for
50 | technical or licensing (LGPL) reasons. If you want to build a DLL,
51 | run the configure script with the argument "-library". Also see
52 | the note about usage below.
53 |
54 | (Components that are Qt plugins, e.g. styles and image formats,
55 | are by default built as a plugin DLL.)
56 |
57 | The configure script will prompt you in some cases for further
58 | information. Answer these questions and carefully read the license text
59 | before accepting the license conditions. The package cannot be used if
60 | you do not accept the license conditions.
61 |
62 | 3. Building the component and examples (when required).
63 |
64 | If a DLL is to be built, or if you would like to build the
65 | examples, next give the commands
66 |
67 | qmake
68 | make [or nmake if your are using Microsoft Visual C++]
69 |
70 | The example program(s) can be found in the directory called
71 | "examples" or "example".
72 |
73 | Components that are Qt plugins, e.g. styles and image formats, are
74 | ready to be used as soon as they are built, so the rest of this
75 | installation instruction can be skipped.
76 |
77 | 4. Building the Qt Designer plugin (optional).
78 |
79 | Some of the widget components are provided with plugins for Qt
80 | Designer. To build and install the plugin, cd into the
81 | some-package/plugin directory and give the commands
82 |
83 | qmake
84 | make [or nmake if your are using Microsoft Visual C++]
85 |
86 | Restart Qt Designer to make it load the new widget plugin.
87 |
88 | Note: If you are using the built-in Qt Designer from the Qt Visual
89 | Studio Integration, you will need to manually copy the plugin DLL
90 | file, i.e. copy
91 | %QTDIR%\plugins\designer\some-component.dll
92 | to the Qt Visual Studio Integration plugin path, typically:
93 | C:\Program Files\Trolltech\Qt VS Integration\plugins
94 |
95 | Note: If you for some reason are using a Qt Designer that is built
96 | in debug mode, you will need to build the plugin in debug mode
97 | also. Edit the file plugin.pro in the plugin directory, changing
98 | 'release' to 'debug' in the CONFIG line, before running qmake.
99 |
100 |
101 |
102 | Solutions components are intended to be used directly from the package
103 | directory during development, so there is no 'make install' procedure.
104 |
105 |
106 | Using a component in your project
107 | ---------------------------------
108 |
109 | To use this component in your project, add the following line to the
110 | project's .pro file (or do the equivalent in your IDE):
111 |
112 | include(your-install-dir/some-package/src/some-package.pri)
113 |
114 | This adds the package's sources and headers to the SOURCES and HEADERS
115 | project variables respectively (or, if the component has been
116 | configured as a DLL, it adds that library to the LIBS variable), and
117 | updates INCLUDEPATH to contain the package's src
118 | directory. Additionally, the .pri file may include some dependencies
119 | needed by the package.
120 |
121 | To include a header file from the package in your sources, you can now
122 | simply use:
123 |
124 | #include
125 |
126 | or alternatively, in pre-Qt 4 style:
127 |
128 | #include
129 |
130 | Refer to the documentation to see the classes and headers this
131 | components provides.
132 |
133 |
134 |
135 | Install documentation (optional)
136 | --------------------------------
137 |
138 | The HTML documentation for the package's classes is located in the
139 | your-install-dir/some-package/doc/html/index.html. You can open this
140 | file and read the documentation with any web browser.
141 |
142 | To install the documentation into Qt Assistant (for Qt version 4.4 and
143 | later):
144 |
145 | 1. In Assistant, open the Edit->Preferences dialog and choose the
146 | Documentation tab. Click the Add... button and select the file
147 | your-install-dir/some-package/doc/html/some-package.qch
148 |
149 | For Qt versions prior to 4.4, do instead the following:
150 |
151 | 1. The directory your-install-dir/some-package/doc/html contains a
152 | file called some-package.dcf. Execute the following commands in a
153 | shell, command prompt or terminal window:
154 |
155 | cd your-install-dir/some-package/doc/html/
156 | assistant -addContentFile some-package.dcf
157 |
158 | The next time you start Qt Assistant, you can access the package's
159 | documentation.
160 |
161 |
162 | Removing the documentation from assistant
163 | -----------------------------------------
164 |
165 | If you have installed the documentation into Qt Assistant, and want to uninstall it, do as follows, for Qt version 4.4 and later:
166 |
167 | 1. In Assistant, open the Edit->Preferences dialog and choose the
168 | Documentation tab. In the list of Registered Documentation, select
169 | the item com.nokia.qtsolutions.some-package_version, and click
170 | the Remove button.
171 |
172 | For Qt versions prior to 4.4, do instead the following:
173 |
174 | 1. The directory your-install-dir/some-package/doc/html contains a
175 | file called some-package.dcf. Execute the following commands in a
176 | shell, command prompt or terminal window:
177 |
178 | cd your-install-dir/some-package/doc/html/
179 | assistant -removeContentFile some-package.dcf
180 |
181 |
182 |
183 | Using the component as a DLL
184 | ----------------------------
185 |
186 | 1. Normal components
187 |
188 | The shared library (DLL) is built and placed in the
189 | some-package/lib directory. It is intended to be used directly
190 | from there during development. When appropriate, both debug and
191 | release versions are built, since the run-time linker will in some
192 | cases refuse to load a debug-built DLL into a release-built
193 | application or vice versa.
194 |
195 | The following steps are taken by default to help the dynamic
196 | linker to locate the DLL at run-time (during development):
197 |
198 | Unix: The some-package.pri file will add linker instructions to
199 | add the some-package/lib directory to the rpath of the
200 | executable. (When distributing, or if your system does not support
201 | rpath, you can copy the shared library to another place that is
202 | searched by the dynamic linker, e.g. the "lib" directory of your
203 | Qt installation.)
204 |
205 | Mac: The full path to the library is hardcoded into the library
206 | itself, from where it is copied into the executable at link time,
207 | and ready by the dynamic linker at run-time. (When distributing,
208 | you will want to edit these hardcoded paths in the same way as for
209 | the Qt DLLs. Refer to the document "Deploying an Application on
210 | Mac OS X" in the Qt Reference Documentation.)
211 |
212 | Windows: the .dll file(s) are copied into the "bin" directory of
213 | your Qt installation. The Qt installation will already have set up
214 | that directory to be searched by the dynamic linker.
215 |
216 |
217 | 2. Plugins
218 |
219 | For Qt Solutions plugins (e.g. image formats), both debug and
220 | release versions of the plugin are built by default when
221 | appropriate, since in some cases the release Qt library will not
222 | load a debug plugin, and vice versa. The plugins are automatically
223 | copied into the plugins directory of your Qt installation when
224 | built, so no further setup is required.
225 |
226 | Plugins may also be built statically, i.e. as a library that will be
227 | linked into your application executable, and so will not need to
228 | be redistributed as a separate plugin DLL to end users. Static
229 | building is required if Qt itself is built statically. To do it,
230 | just add "static" to the CONFIG variable in the plugin/plugin.pro
231 | file before building. Refer to the "Static Plugins" section in the
232 | chapter "How to Create Qt Plugins" for explanation of how to use a
233 | static plugin in your application. The source code of the example
234 | program(s) will also typically contain the relevant instructions
235 | as comments.
236 |
237 |
238 |
239 | Uninstalling
240 | ------------
241 |
242 | The following command will remove any fils that have been
243 | automatically placed outside the package directory itself during
244 | installation and building
245 |
246 | make distclean [or nmake if your are using Microsoft Visual C++]
247 |
248 | If Qt Assistant documentation or Qt Designer plugins have been
249 | installed, they can be uninstalled manually, ref. above.
250 |
251 |
252 | Enjoy! :)
253 |
254 | - The Qt Solutions Team.
255 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/README.TXT:
--------------------------------------------------------------------------------
1 | Qt Solutions Component: Service
2 |
3 | The QtService component is useful for developing Windows services
4 | and Unix daemons.
5 |
6 |
7 |
8 | Version history:
9 |
10 | 2.0: - Reimplemented for Qt 4 with improved API.
11 |
12 | 2.1: - More feedback while installing / uninstalling.
13 | - Unix: Documentation about installing service improved.
14 | - Windows: Added account and password arguments to install().
15 | - Windows: Report status correcty when stopping through the
16 | controller.
17 | - Windows: Send command IDs correctly.
18 |
19 | 2.2: - Unix: logMessage() works properly with '%' characters.
20 | - Windows: Dependency on the QtGui library removed.
21 |
22 | 2.3: - Unix: Using QProcess in a service no longer leaves zombie
23 | processes around.
24 | - Windows: Place controller's receiver object in proper thread.
25 | (makes QtService work with Qt 4.2).
26 | - Compilation fixes for MinGW.
27 |
28 | 2.4: - Windows: Do net require Administrator privileges just to
29 | start service.
30 | - Improved command-line help text.
31 | - Document the caveats of using GUI services, including that Vista
32 | does not support it.
33 | - Added -w(ait) argument to controller example
34 | - Added doc about usage on Windows Vista
35 | - Windows: Fix: GUI services would terminate on logoff.
36 | - Windows: internal redesign of threading. Fixes issue where
37 | signal/slot connections created before start() would not work.
38 | Fixes problem/warning about QApplication not created in main
39 | thread.
40 |
41 | 2.5: - Fixes: crash on OS X Leopard. Note: On mac, main() will now
42 | be executed both in the starting process and in the forked,
43 | service process. This is consistent with the behaviour on Windows.
44 | - Fixes: Improved logging of multi-line messages on Unix.
45 |
46 | 2.6: - Misc. minor fixes.
47 | - LGPL release.
48 |
49 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/buildlib/buildlib.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE=lib
2 | CONFIG += qt dll qtservice-buildlib
3 | mac:CONFIG += absolute_library_soname
4 | win32|mac:!wince*:!win32-msvc:!macx-xcode:CONFIG += debug_and_release build_all
5 | include(../src/qtservice.pri)
6 | TARGET = $$QTSERVICE_LIBNAME
7 | DESTDIR = $$QTSERVICE_LIBDIR
8 | win32 {
9 | DLLDESTDIR = $$[QT_INSTALL_BINS]
10 | QMAKE_DISTCLEAN += $$[QT_INSTALL_BINS]\\$${QTSERVICE_LIBNAME}.dll
11 | }
12 | target.path = $$DESTDIR
13 | INSTALLS += target
14 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/common.pri:
--------------------------------------------------------------------------------
1 | exists(config.pri):infile(config.pri, SOLUTIONS_LIBRARY, yes): CONFIG += qtservice-uselib
2 | TEMPLATE += fakelib
3 | QTSERVICE_LIBNAME = QtSolutions_Service-head
4 | CONFIG(debug, debug|release) {
5 | mac:QTSERVICE_LIBNAME = $$member(QTSERVICE_LIBNAME, 0)_debug
6 | else:win32:QTSERVICE_LIBNAME = $$member(QTSERVICE_LIBNAME, 0)d
7 | }
8 | TEMPLATE -= fakelib
9 | QTSERVICE_LIBDIR = $$PWD/lib
10 | unix:qtservice-uselib:!qtservice-buildlib:QMAKE_RPATHDIR += $$QTSERVICE_LIBDIR
11 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/configure:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | if [ "x$1" != "x" -a "x$1" != "x-library" ]; then
4 | echo "Usage: $0 [-library]"
5 | echo
6 | echo "-library: Build the component as a dynamic library (DLL). Default is to"
7 | echo " include the component source code directly in the application."
8 | echo
9 | exit 0
10 | fi
11 |
12 | rm -f config.pri
13 | if [ "x$1" = "x-library" ]; then
14 | echo "Configuring to build this component as a dynamic library."
15 | echo "SOLUTIONS_LIBRARY = yes" > config.pri
16 | fi
17 |
18 | echo
19 | echo "This component is now configured."
20 | echo
21 | echo "To build the component library (if requested) and example(s),"
22 | echo "run qmake and your make command."
23 | echo
24 | echo "To remove or reconfigure, run make distclean."
25 | echo
26 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/configure.bat:
--------------------------------------------------------------------------------
1 | :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
2 | ::
3 | :: Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | :: Contact: http://www.qt-project.org/legal
5 | ::
6 | :: This file is part of the Qt Solutions component.
7 | ::
8 | :: $QT_BEGIN_LICENSE:BSD$
9 | :: You may use this file under the terms of the BSD license as follows:
10 | ::
11 | :: "Redistribution and use in source and binary forms, with or without
12 | :: modification, are permitted provided that the following conditions are
13 | :: met:
14 | :: * Redistributions of source code must retain the above copyright
15 | :: notice, this list of conditions and the following disclaimer.
16 | :: * Redistributions in binary form must reproduce the above copyright
17 | :: notice, this list of conditions and the following disclaimer in
18 | :: the documentation and/or other materials provided with the
19 | :: distribution.
20 | :: * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | :: of its contributors may be used to endorse or promote products derived
22 | :: from this software without specific prior written permission.
23 | ::
24 | ::
25 | :: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | :: "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | :: LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | :: A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | :: OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | :: SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | :: LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | :: DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | :: THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | :: (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | :: OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | ::
37 | :: $QT_END_LICENSE$
38 | ::
39 | :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
40 |
41 | @echo off
42 |
43 | rem
44 | rem "Main"
45 | rem
46 |
47 | if not "%1"=="" (
48 | if not "%1"=="-library" (
49 | call :PrintUsage
50 | goto EOF
51 | )
52 | )
53 |
54 | if exist config.pri. del config.pri
55 | if "%1"=="-library" (
56 | echo Configuring to build this component as a dynamic library.
57 | echo SOLUTIONS_LIBRARY = yes > config.pri
58 | )
59 |
60 | echo .
61 | echo This component is now configured.
62 | echo .
63 | echo To build the component library (if requested) and example(s),
64 | echo run qmake and your make or nmake command.
65 | echo .
66 | echo To remove or reconfigure, run make (nmake) distclean.
67 | echo .
68 | goto EOF
69 |
70 | :PrintUsage
71 | echo Usage: configure.bat [-library]
72 | echo .
73 | echo -library: Build the component as a dynamic library (DLL). Default is to
74 | echo include the component source directly in the application.
75 | echo A DLL may be preferable for technical or licensing (LGPL) reasons.
76 | echo .
77 | goto EOF
78 |
79 |
80 | :EOF
81 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/classic.css:
--------------------------------------------------------------------------------
1 | BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV {
2 | font-family: Arial, Geneva, Helvetica, sans-serif;
3 | }
4 | H1 {
5 | text-align: center;
6 | font-size: 160%;
7 | }
8 | H2 {
9 | font-size: 120%;
10 | }
11 | H3 {
12 | font-size: 100%;
13 | }
14 |
15 | h3.fn,span.fn
16 | {
17 | background-color: #eee;
18 | border-width: 1px;
19 | border-style: solid;
20 | border-color: #ddd;
21 | font-weight: bold;
22 | padding: 6px 0px 6px 10px;
23 | margin: 42px 0px 0px 0px;
24 | }
25 |
26 | hr {
27 | border: 0;
28 | color: #a0a0a0;
29 | background-color: #ccc;
30 | height: 1px;
31 | width: 100%;
32 | text-align: left;
33 | margin: 34px 0px 34px 0px;
34 | }
35 |
36 | table.valuelist {
37 | border-width: 1px 1px 1px 1px;
38 | border-style: solid;
39 | border-color: #dddddd;
40 | border-collapse: collapse;
41 | background-color: #f0f0f0;
42 | }
43 |
44 | table.indextable {
45 | border-width: 1px 1px 1px 1px;
46 | border-style: solid;
47 | border-collapse: collapse;
48 | background-color: #f0f0f0;
49 | border-color:#555;
50 | font-size: 100%;
51 | }
52 |
53 | table td.largeindex {
54 | border-width: 1px 1px 1px 1px;
55 | border-collapse: collapse;
56 | background-color: #f0f0f0;
57 | border-color:#555;
58 | font-size: 120%;
59 | }
60 |
61 | table.valuelist th {
62 | border-width: 1px 1px 1px 2px;
63 | padding: 4px;
64 | border-style: solid;
65 | border-color: #666;
66 | color:white;
67 | background-color:#666;
68 | }
69 |
70 | th.titleheader {
71 | border-width: 1px 0px 1px 0px;
72 | padding: 2px;
73 | border-style: solid;
74 | border-color: #666;
75 | color:white;
76 | background-color:#555;
77 | background-image:url('images/gradient.png')};
78 | background-repeat: repeat-x;
79 | font-size: 100%;
80 | }
81 |
82 |
83 | th.largeheader {
84 | border-width: 1px 0px 1px 0px;
85 | padding: 4px;
86 | border-style: solid;
87 | border-color: #444;
88 | color:white;
89 | background-color:#555555;
90 | font-size: 120%;
91 | }
92 |
93 | p {
94 |
95 | margin-left: 4px;
96 | margin-top: 8px;
97 | margin-bottom: 8px;
98 | }
99 |
100 | a:link
101 | {
102 | color: #0046ad;
103 | text-decoration: none
104 | }
105 |
106 | a:visited
107 | {
108 | color: #672967;
109 | text-decoration: none
110 | }
111 |
112 | a.obsolete
113 | {
114 | color: #661100;
115 | text-decoration: none
116 | }
117 |
118 | a.compat
119 | {
120 | color: #661100;
121 | text-decoration: none
122 | }
123 |
124 | a.obsolete:visited
125 | {
126 | color: #995500;
127 | text-decoration: none
128 | }
129 |
130 | a.compat:visited
131 | {
132 | color: #995500;
133 | text-decoration: none
134 | }
135 |
136 | body
137 | {
138 | background: #ffffff;
139 | color: black
140 | }
141 |
142 | table.generic, table.annotated
143 | {
144 | border-width: 1px;
145 | border-color:#bbb;
146 | border-style:solid;
147 | border-collapse:collapse;
148 | }
149 |
150 | table td.memItemLeft {
151 | width: 180px;
152 | padding: 2px 0px 0px 8px;
153 | margin: 4px;
154 | border-width: 1px;
155 | border-color: #E0E0E0;
156 | border-style: none;
157 | font-size: 100%;
158 | white-space: nowrap
159 | }
160 |
161 | table td.memItemRight {
162 | padding: 2px 8px 0px 8px;
163 | margin: 4px;
164 | border-width: 1px;
165 | border-color: #E0E0E0;
166 | border-style: none;
167 | font-size: 100%;
168 | }
169 |
170 | table tr.odd {
171 | background: #f0f0f0;
172 | color: black;
173 | }
174 |
175 | table tr.even {
176 | background: #e4e4e4;
177 | color: black;
178 | }
179 |
180 | table.annotated th {
181 | padding: 3px;
182 | text-align: left
183 | }
184 |
185 | table.annotated td {
186 | padding: 3px;
187 | }
188 |
189 | table tr pre
190 | {
191 | padding-top: 0px;
192 | padding-bottom: 0px;
193 | padding-left: 0px;
194 | padding-right: 0px;
195 | border: none;
196 | background: none
197 | }
198 |
199 | tr.qt-style
200 | {
201 | background: #96E066;
202 | color: black
203 | }
204 |
205 | body pre
206 | {
207 | padding: 0.2em;
208 | border: #e7e7e7 1px solid;
209 | background: #f1f1f1;
210 | color: black
211 | }
212 |
213 | table tr.qt-code pre
214 | {
215 | padding: 0.2em;
216 | border: #e7e7e7 1px solid;
217 | background: #f1f1f1;
218 | color: black
219 | }
220 |
221 | span.preprocessor, span.preprocessor a
222 | {
223 | color: darkblue;
224 | }
225 |
226 | span.comment
227 | {
228 | color: darkred;
229 | font-style: italic
230 | }
231 |
232 | span.string,span.char
233 | {
234 | color: darkgreen;
235 | }
236 |
237 | .title
238 | {
239 | text-align: center
240 | }
241 |
242 | .subtitle
243 | {
244 | font-size: 0.8em
245 | }
246 |
247 | .small-subtitle
248 | {
249 | font-size: 0.65em
250 | }
251 |
252 | .qmlitem {
253 | padding: 0;
254 | }
255 |
256 | .qmlname {
257 | white-space: nowrap;
258 | }
259 |
260 | .qmltype {
261 | text-align: center;
262 | font-size: 160%;
263 | }
264 |
265 | .qmlproto {
266 | background-color: #eee;
267 | border-width: 1px;
268 | border-style: solid;
269 | border-color: #ddd;
270 | font-weight: bold;
271 | padding: 6px 10px 6px 10px;
272 | margin: 42px 0px 0px 0px;
273 | }
274 |
275 | .qmlreadonly {
276 | float: right;
277 | color: red
278 | }
279 |
280 | .qmldoc {
281 | }
282 |
283 | *.qmlitem p {
284 | }
285 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/images/qt-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FinixLei/QtProjects/8092222c35a70ca37d8f9a99f91cf925ffa8253c/TestSignalTrigger/TestQtService/qtservice/doc/html/images/qt-logo.png
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | Service
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Service
16 |
17 |
18 | Description
19 | The QtService component is useful for developing Windows services and Unix daemons.
20 | The project provides a QtService template class that can be used to implement service applications, and a QtServiceController class to control a service.
21 | On Windows systems the implementation uses the Service Control Manager.
22 | On Unix systems services are implemented as daemons.
23 |
24 | Classes
25 |
30 |
31 | Examples
32 |
37 |
38 | Tested platforms
39 |
40 | Qt 4.4, 4.5 / Windows XP / MSVC.NET 2005
41 | Qt 4.4, 4.5 / Linux / gcc
42 | Qt 4.4, 4.5 / MacOS X 10.5 / gcc
43 |
44 |
45 |
46 | Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)
47 | Trademarks
48 | Qt Solutions
49 |
50 |
51 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/qtservice-example-controller.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | A simple Service Controller
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
A simple Service Controller
16 |
17 | It is a very simple implementation of universal command-line controller. This controller can install and control any service written using QtService component. It demonstrates how to use QtServiceController class. On Windows, this is an alternative to using the "Services" Administrative Tool or the built-in sc.exe command-line tool to control services.
18 | A note about services on Windows Vista: Installing/uninstalling and starting/stopping services requires security privileges. The simplest way to achieve this is to set the "Run as Administrator" property on the executable (right-click the executable file, select Properties, and choose the Compatibilty tab in the Properties dialog). This applies even if you are logged in as Administrator. Also, the command-line shell should be started with "Run as Administrator". Note that the service itself does not need special privileges to run. Only if you want the service to be able to install itself (the -i option) or similar, then the service will need to be run as Administrator. Otherwise, the recommended procedure is to use a controller such as this example and/or the "Services" Administrative Tool to manage the service.
19 | A usability hint: in some circumstances, e.g. when running this example on Windows Vista with the "Run as Administrator" property set, output will be sent to a shell window which will close immediately upon termination, not leaving the user enough time to read the output. In such cases, append the -w(ait) argument, which will make the controller wait for a keypress before terminating.
20 | Here is the complete source code:
21 |
57 |
58 | #include <QtCore/QStringList>
59 | #include <QtCore/QDir>
60 | #include <QtCore/QSettings>
61 | #include "qtservice.h"
62 |
63 | int processArgs(int argc, char **argv)
64 | {
65 | if (argc > 2) {
66 | QString arg1(argv[1]);
67 | if (arg1 == QLatin1String("-i") ||
68 | arg1 == QLatin1String("-install")) {
69 | if (argc > 2) {
70 | QString account;
71 | QString password;
72 | QString path(argv[2]);
73 | if (argc > 3)
74 | account = argv[3];
75 | if (argc > 4)
76 | password = argv[4];
77 | printf("The service %s installed.\n",
78 | (QtServiceController::install(path, account, password) ? "was" : "was not"));
79 | return 0;
80 | }
81 | } else {
82 | QString serviceName(argv[1]);
83 | QtServiceController controller(serviceName);
84 | QString option(argv[2]);
85 | if (option == QLatin1String("-u") ||
86 | option == QLatin1String("-uninstall")) {
87 | printf("The service \"%s\" %s uninstalled.\n",
88 | controller.serviceName().toLatin1().constData(),
89 | (controller.uninstall() ? "was" : "was not"));
90 | return 0;
91 | } else if (option == QLatin1String("-s") ||
92 | option == QLatin1String("-start")) {
93 | QStringList args;
94 | for (int i = 3; i < argc; ++i)
95 | args.append(QString::fromLocal8Bit(argv[i]));
96 | printf("The service \"%s\" %s started.\n",
97 | controller.serviceName().toLatin1().constData(),
98 | (controller.start(args) ? "was" : "was not"));
99 | return 0;
100 | } else if (option == QLatin1String("-t") ||
101 | option == QLatin1String("-terminate")) {
102 | printf("The service \"%s\" %s stopped.\n",
103 | controller.serviceName().toLatin1().constData(),
104 | (controller.stop() ? "was" : "was not"));
105 | return 0;
106 | } else if (option == QLatin1String("-p") ||
107 | option == QLatin1String("-pause")) {
108 | printf("The service \"%s\" %s paused.\n",
109 | controller.serviceName().toLatin1().constData(),
110 | (controller.pause() ? "was" : "was not"));
111 | return 0;
112 | } else if (option == QLatin1String("-r") ||
113 | option == QLatin1String("-resume")) {
114 | printf("The service \"%s\" %s resumed.\n",
115 | controller.serviceName().toLatin1().constData(),
116 | (controller.resume() ? "was" : "was not"));
117 | return 0;
118 | } else if (option == QLatin1String("-c") ||
119 | option == QLatin1String("-command")) {
120 | if (argc > 3) {
121 | QString codestr(argv[3]);
122 | int code = codestr.toInt();
123 | printf("The command %s sent to the service \"%s\".\n",
124 | (controller.sendCommand(code) ? "was" : "was not"),
125 | controller.serviceName().toLatin1().constData());
126 | return 0;
127 | }
128 | } else if (option == QLatin1String("-v") ||
129 | option == QLatin1String("-version")) {
130 | bool installed = controller.isInstalled();
131 | printf("The service\n"
132 | "\t\"%s\"\n\n", controller.serviceName().toLatin1().constData());
133 | printf("is %s", (installed ? "installed" : "not installed"));
134 | printf(" and %s\n\n", (controller.isRunning() ? "running" : "not running"));
135 | if (installed) {
136 | printf("path: %s\n", controller.serviceFilePath().toLatin1().data());
137 | printf("description: %s\n", controller.serviceDescription().toLatin1().data());
138 | printf("startup: %s\n", controller.startupType() == QtServiceController::AutoStartup ? "Auto" : "Manual");
139 | }
140 | return 0;
141 | }
142 | }
143 | }
144 | printf("controller [-i PATH | SERVICE_NAME [-v | -u | -s | -t | -p | -r | -c CODE] | -h] [-w]\n\n"
145 | "\t-i(nstall) PATH\t: Install the service\n"
146 | "\t-v(ersion)\t: Print status of the service\n"
147 | "\t-u(ninstall)\t: Uninstall the service\n"
148 | "\t-s(tart)\t: Start the service\n"
149 | "\t-t(erminate)\t: Stop the service\n"
150 | "\t-p(ause)\t: Pause the service\n"
151 | "\t-r(esume)\t: Resume the service\n"
152 | "\t-c(ommand) CODE\t: Send a command to the service\n"
153 | "\t-h(elp)\t\t: Print this help info\n"
154 | "\t-w(ait)\t\t: Wait for keypress when done\n");
155 | return 0;
156 | }
157 |
158 | int main(int argc, char **argv)
159 | {
160 | #if !defined(Q_OS_WIN)
161 |
162 |
163 | QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, QDir::tempPath());
164 | qWarning("(Example uses dummy settings file: %s/QtSoftware.conf)", QDir::tempPath().toLatin1().constData());
165 | #endif
166 |
167 | int result = processArgs(argc, argv);
168 |
169 | if (QString::fromLocal8Bit(argv[argc-1]) == QLatin1String("-w") ||
170 | QString::fromLocal8Bit(argv[argc-1]) == QLatin1String("-wait")) {
171 | printf("\nPress Enter to continue...");
172 | QFile input;
173 | input.open(stdin, QIODevice::ReadOnly);
174 | input.readLine();
175 | printf("\n");
176 | }
177 |
178 | return result;
179 | }
180 |
181 |
182 | Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)
183 | Trademarks
184 | Qt Solutions
185 |
186 |
187 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/qtservice-example-interactive.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | An Interactive Service
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
An Interactive Service
16 |
17 | This example implements a service with a simple user interface.
18 | Services are usually non-interactive console applications. User interaction, if required, is usually implemented in a separate, normal GUI application that communicates with the service through an IPC channel. For simple communication, QtServiceController::sendCommand () and QtService::processCommand () may be used, possibly in combination with a shared settings file. For more complex, interactive communication, a custom IPC channel should be used, e.g. based on Qt's networking classes.
19 | However, although not recommended in the general case, in certain circumstances a service may provide a GUI itself. This is typically only possible if the service process is run as the same user as the one that is logged in, so that it will have access to the screen. Note however that on Windows Vista, service GUIs are not allowed at all, since services run in a diferent session than all user sessions, for security reasons.
20 | This example demonstrates how to subclass the QtService class, the use of start(), stop(), pause(), resume(), and how to use processCommand() to receive control commands while running.
21 | Here is the complete source code:
22 |
58 |
59 | #include <QtGui/QApplication>
60 | #include <QtGui/QDesktopWidget>
61 | #include <QtGui/QLabel>
62 | #include <QtCore/QDir>
63 | #include <QtCore/QSettings>
64 | #include "qtservice.h"
65 |
66 | class InteractiveService : public QtService<QApplication>
67 | {
68 | public:
69 | InteractiveService(int argc, char **argv);
70 | ~InteractiveService();
71 |
72 | protected:
73 |
74 | void start();
75 | void stop();
76 | void pause();
77 | void resume();
78 | void processCommand(int code);
79 |
80 | private:
81 | QLabel *gui;
82 | };
83 |
84 | InteractiveService::InteractiveService(int argc, char **argv)
85 | : QtService<QApplication>(argc, argv, "Qt Interactive Service"), gui(0)
86 | {
87 | setServiceDescription("A Qt service with user interface.");
88 | setServiceFlags(QtServiceBase::CanBeSuspended);
89 | }
90 |
91 | InteractiveService::~InteractiveService()
92 | {
93 | }
94 |
95 | void InteractiveService::start()
96 | {
97 | #if defined(Q_OS_WIN)
98 | if ((QSysInfo::WindowsVersion & QSysInfo::WV_NT_based) &&
99 | (QSysInfo::WindowsVersion >= QSysInfo::WV_VISTA)) {
100 | logMessage( "Service GUI not allowed on Windows Vista. See the documentation for this example for more information.", QtServiceBase::Error );
101 | return;
102 | }
103 | #endif
104 |
105 | qApp->setQuitOnLastWindowClosed(false);
106 |
107 | gui = new QLabel("Service", 0, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
108 | gui->move(QApplication::desktop()->availableGeometry().topLeft());
109 | gui->show();
110 | }
111 |
112 | void InteractiveService::stop()
113 | {
114 | delete gui;
115 | }
116 |
117 | void InteractiveService::pause()
118 | {
119 | if (gui)
120 | gui->hide();
121 | }
122 |
123 | void InteractiveService::resume()
124 | {
125 | if (gui)
126 | gui->show();
127 | }
128 |
129 | void InteractiveService::processCommand(int code)
130 | {
131 | gui->setText("Command code " + QString::number(code));
132 | gui->adjustSize();
133 | }
134 |
135 | int main(int argc, char **argv)
136 | {
137 | #if !defined(Q_OS_WIN)
138 |
139 |
140 | QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, QDir::tempPath());
141 | qWarning("(Example uses dummy settings file: %s/QtSoftware.conf)", QDir::tempPath().toLatin1().constData());
142 | #endif
143 | InteractiveService service(argc, argv);
144 | return service.exec();
145 | }
146 |
147 |
148 | Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)
149 | Trademarks
150 | Qt Solutions
151 |
152 |
153 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/qtservice-example-server.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | A simple HTTP Server
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
A simple HTTP Server
16 |
17 | It is a very simple implementation of a HTTP daemon that listens on chosen port (defaultly 8080) and sends back a simple HTML page back for every GET request it gets. After sending the page, it closes the connection.
18 |
19 | class HttpDaemon : public QTcpServer
20 | {
21 | Q_OBJECT
22 | public:
23 | HttpDaemon(quint16 port, QObject* parent = 0)
24 | : QTcpServer(parent), disabled(false)
25 | {
26 | listen(QHostAddress::Any, port);
27 | }
28 |
29 | void incomingConnection(int socket)
30 | {
31 | if (disabled)
32 | return;
33 |
34 |
35 |
36 |
37 |
38 | QTcpSocket* s = new QTcpSocket(this);
39 | connect(s, SIGNAL(readyRead()), this, SLOT(readClient()));
40 | connect(s, SIGNAL(disconnected()), this, SLOT(discardClient()));
41 | s->setSocketDescriptor(socket);
42 |
43 | QtServiceBase::instance()->logMessage("New Connection");
44 | }
45 |
46 | void pause()
47 | {
48 | disabled = true;
49 | }
50 |
51 | void resume()
52 | {
53 | disabled = false;
54 | }
55 |
56 | private slots:
57 | void readClient()
58 | {
59 | if (disabled)
60 | return;
61 |
62 |
63 |
64 |
65 | QTcpSocket* socket = (QTcpSocket*)sender();
66 | if (socket->canReadLine()) {
67 | QStringList tokens = QString(socket->readLine()).split(QRegExp("[ \r\n][ \r\n]*"));
68 | if (tokens[0] == "GET") {
69 | QTextStream os(socket);
70 | os.setAutoDetectUnicode(true);
71 | os << "HTTP/1.0 200 Ok\r\n"
72 | "Content-Type: text/html; charset=\"utf-8\"\r\n"
73 | "\r\n"
74 | "<h1>Nothing to see here</h1>\n"
75 | << QDateTime::currentDateTime().toString() << "\n";
76 | socket->close();
77 |
78 | QtServiceBase::instance()->logMessage("Wrote to client");
79 |
80 | if (socket->state() == QTcpSocket::UnconnectedState) {
81 | delete socket;
82 | QtServiceBase::instance()->logMessage("Connection closed");
83 | }
84 | }
85 | }
86 | }
87 | void discardClient()
88 | {
89 | QTcpSocket* socket = (QTcpSocket*)sender();
90 | socket->deleteLater();
91 |
92 | QtServiceBase::instance()->logMessage("Connection closed");
93 | }
94 |
95 | private:
96 | bool disabled;
97 | };
98 | The server implementation uses the QtService::logMessage () function to send messages and status reports to the system event log. The server also supports a paused state in which case incoming requests are ignored.
99 | The HttpService class subclasses QtService to implement the service functionality.
100 | class HttpService : public QtService<QCoreApplication>
101 | {
102 | public:
103 | HttpService(int argc, char **argv)
104 | : QtService<QCoreApplication>(argc, argv, "Qt HTTP Daemon")
105 | {
106 | setServiceDescription("A dummy HTTP service implemented with Qt");
107 | setServiceFlags(QtServiceBase::CanBeSuspended);
108 | }
109 | The constructor calls the QtService constructor instantiated with QCoreApplication since our service will not use GUI. The first two parameters of our constructor are passed to QtService . The last parameter, "Qt HTTP Daemon", is the name of the service.
110 | protected:
111 | void start()
112 | {
113 | QCoreApplication *app = application();
114 |
115 | quint16 port = (app->argc() > 1) ?
116 | QString::fromLocal8Bit(app->argv()[1]).toUShort() : 8080;
117 | daemon = new HttpDaemon(port, app);
118 |
119 | if (!daemon->isListening()) {
120 | logMessage(QString("Failed to bind to port %1").arg(daemon->serverPort()), QtServiceBase::Error);
121 | app->quit();
122 | }
123 | }
124 | The implementation of start() first checks if the user passed a port number. If yes that port is used by server to listen on. Otherwise default 8080 port is used. Then creates an instance of the HTTP server using operator new, passing the application object as the parent to ensure that the object gets destroyed.
125 | void pause()
126 | {
127 | daemon->pause();
128 | }
129 |
130 | void resume()
131 | {
132 | daemon->resume();
133 | }
134 |
135 | private:
136 | HttpDaemon *daemon;
137 | };
138 | The implementations of pause() and resume() forward the request to the server object.
139 | #include "main.moc"
140 |
141 | int main(int argc, char **argv)
142 | {
143 | #if !defined(Q_OS_WIN)
144 |
145 |
146 | QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, QDir::tempPath());
147 | qWarning("(Example uses dummy settings file: %s/QtSoftware.conf)", QDir::tempPath().toLatin1().constData());
148 | #endif
149 | HttpService service(argc, argv);
150 | return service.exec();
151 | }
152 | The main entry point function creates the service object and uses the exec() function to execute the service.
153 |
154 |
155 | Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)
156 | Trademarks
157 | Qt Solutions
158 |
159 |
160 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/qtservice-members.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | List of All Members for QtService
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
List of All Members for QtService
16 | This is the complete list of members for QtService , including inherited members.
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | logMessage ( const QString &, MessageType, int, uint, const QByteArray & )
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | startupType () const : QtServiceController::StartupType
42 |
43 |
44 |
45 |
46 |
47 |
48 | Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)
49 | Trademarks
50 | Qt Solutions
51 |
52 |
53 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/qtservice.dcf:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | QtService
6 | application
7 | createApplication
8 | executeApplication
9 |
10 |
11 |
12 | QtServiceBase
13 | MessageType
14 | QtServiceBase::Warning
15 | QtServiceBase::Error
16 | QtServiceBase::Success
17 | QtServiceBase::Information
18 | ServiceFlag
19 | ServiceFlags
20 | QtServiceBase::Default
21 | QtServiceBase::NeedsStopOnShutdown
22 | QtServiceBase::CannotBeStopped
23 | QtServiceBase::CanBeSuspended
24 | createApplication
25 | exec
26 | executeApplication
27 | instance
28 | logMessage
29 | pause
30 | processCommand
31 | resume
32 | serviceDescription
33 | serviceFlags
34 | serviceName
35 | setServiceDescription
36 | setServiceFlags
37 | setStartupType
38 | start
39 | startupType
40 | stop
41 |
42 |
43 |
44 | QtServiceController
45 | StartupType
46 | QtServiceController::AutoStartup
47 | QtServiceController::ManualStartup
48 | install
49 | isInstalled
50 | isRunning
51 | pause
52 | resume
53 | sendCommand
54 | serviceDescription
55 | serviceFilePath
56 | serviceName
57 | start
58 | startupType
59 | stop
60 | uninstall
61 |
62 |
63 |
64 |
65 |
66 | A simple HTTP Server
67 |
68 |
69 | A simple Service Controller
70 |
71 |
72 | An Interactive Service
73 |
74 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/qtservice.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | QtService Class Reference
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
QtService Class Reference
16 | The QtService is a convenient template class that allows you to create a service for a particular application type. More...
17 | #include <QtService> Inherits QtServiceBase .
18 |
21 |
22 |
23 | Public Functions
24 |
28 |
31 |
32 |
33 | Protected Functions
34 |
37 |
38 |
39 | Reimplemented Protected Functions
40 |
44 |
47 | Additional Inherited Members
48 |
51 |
52 |
53 | Detailed Description
54 | The QtService is a convenient template class that allows you to create a service for a particular application type.
55 | A Windows service or Unix daemon (a "service"), is a program that runs "in the background" independently of whether a user is logged in or not. A service is often set up to start when the machine boots up, and will typically run continuously as long as the machine is on.
56 | Services are usually non-interactive console applications. User interaction, if required, is usually implemented in a separate, normal GUI application that communicates with the service through an IPC channel. For simple communication, QtServiceController::sendCommand () and QtService::processCommand () may be used, possibly in combination with a shared settings file. For more complex, interactive communication, a custom IPC channel should be used, e.g. based on Qt's networking classes. (In certain circumstances, a service may provide a GUI itself, ref. the "interactive" example documentation).
57 | Note: On Unix systems, this class relies on facilities provided by the QtNetwork module, provided as part of the Qt Open Source Edition and certain Qt Commercial Editions .
58 | The QtService class functionality is inherited from QtServiceBase , but in addition the QtService class binds an instance of QtServiceBase with an application type.
59 | Typically, you will create a service by subclassing the QtService template class. For example:
60 | class MyService : public QtService<QApplication>
61 | {
62 | public:
63 | MyService(int argc, char **argv);
64 | ~MyService();
65 |
66 | protected:
67 | void start();
68 | void stop();
69 | void pause();
70 | void resume();
71 | void processCommand(int code);
72 | };
73 | The application type can be QCoreApplication for services without GUI, QApplication for services with GUI or you can use your own custom application type.
74 | You must reimplement the QtServiceBase::start () function to perform the service's work. Usually you create some main object on the heap which is the heart of your service.
75 | In addition, you might want to reimplement the QtServiceBase::pause (), QtServiceBase::processCommand (), QtServiceBase::resume () and QtServiceBase::stop () to intervene the service's process on controller requests. You can control any given service using an instance of the QtServiceController class which also allows you to control services from separate applications. The mentioned functions are all virtual and won't do anything unless they are reimplemented.
76 | Your custom service is typically instantiated in the application's main function. Then the main function will call your service's exec () function, and return the result of that call. For example:
77 | int main(int argc, char **argv)
78 | {
79 | MyService service(argc, argv);
80 | return service.exec();
81 | }
82 | When the exec () function is called, it will parse the service specific arguments passed in argv , perform the required actions, and exit.
83 | If none of the arguments is recognized as service specific, exec () will first call the createApplication () function, then executeApplication () and finally the start () function. In the end, exec () returns while the service continues in its own process waiting for commands from the service controller.
84 | See also QtServiceBase and QtServiceController .
85 |
86 | Member Function Documentation
87 | QtService::QtService ( int argc , char ** argv , const QString & name )
88 | Constructs a QtService object called name . The argc and argv parameters are parsed after the exec () function has been called. Then they are passed to the application's constructor.
89 | There can only be one QtService object in a process.
90 | See also QtServiceBase ().
91 | QtService::~QtService ()
92 | Destroys the service object.
93 | Application * QtService::application () const [protected]
94 | Returns a pointer to the application object.
95 | void QtService::createApplication ( int & argc , char ** argv ) [virtual protected]
96 | Reimplemented from QtServiceBase::createApplication ().
97 | Creates application object of type Application passing argc and argv to its constructor.
98 | int QtService::executeApplication () [virtual protected]
99 | Reimplemented from QtServiceBase::executeApplication ().
100 |
101 |
102 | Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)
103 | Trademarks
104 | Qt Solutions
105 |
106 |
107 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/qtservice.qhp:
--------------------------------------------------------------------------------
1 |
2 |
3 | com.nokia.qtsolutions.qtservice_head
4 | qdoc
5 |
6 | qt
7 | qtservice
8 | solutions
9 |
10 |
11 | qt
12 | qtservice
13 | solutions
14 |
15 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | qtservice-example-controller.html
83 | index.html
84 | qtservice-example-server.html
85 | qtservice-example-interactive.html
86 | qtservicebase.html
87 | qtservice.html
88 | qtservicecontroller.html
89 | classic.css
90 | images/qt-logo.png
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/qtservicebase-members.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | List of All Members for QtServiceBase
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
List of All Members for QtServiceBase
16 | This is the complete list of members for QtServiceBase , including inherited members.
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | logMessage ( const QString &, MessageType, int, uint, const QByteArray & )
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | startupType () const : QtServiceController::StartupType
41 |
42 |
43 |
44 |
45 |
46 |
47 | Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)
48 | Trademarks
49 | Qt Solutions
50 |
51 |
52 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/html/qtservicecontroller-members.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 | List of All Members for QtServiceController
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
List of All Members for QtServiceController
16 | This is the complete list of members for QtServiceController , including inherited members.
17 |
18 |
19 |
20 |
21 |
22 | install ( const QString &, const QString &, const QString & ) : bool
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | start ( const QStringList & ) : bool
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 | Copyright © 2010 Nokia Corporation and/or its subsidiary(-ies)
43 | Trademarks
44 | Qt Solutions
45 |
46 |
47 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/images/qt-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FinixLei/QtProjects/8092222c35a70ca37d8f9a99f91cf925ffa8253c/TestSignalTrigger/TestQtService/qtservice/doc/images/qt-logo.png
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/doc/index.qdoc:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | /*!
42 | \page index.html
43 | \title Service
44 |
45 | \section1 Description
46 |
47 | The QtService component is useful for developing Windows
48 | services and Unix daemons.
49 |
50 |
51 |
52 | The project provides a QtService template class that can be used to
53 | implement service applications, and a QtServiceController class
54 | to control a service.
55 |
56 | On Windows systems the implementation uses the Service Control
57 | Manager.
58 |
59 | On Unix systems services are implemented as daemons.
60 |
61 |
62 |
63 | \section1 Classes
64 | \list
65 | \i QtServiceController \i QtServiceBase \i QtService\endlist
66 |
67 | \section1 Examples
68 | \list
69 | \i \link qtservice-example-interactive.html An Interactive Service \endlink \i \link qtservice-example-server.html A simple HTTP Server \endlink \i \link qtservice-example-controller.html A simple Service Controller \endlink \endlist
70 |
71 |
72 |
73 |
74 |
75 |
76 | \section1 Tested platforms
77 | \list
78 | \i Qt 4.4, 4.5 / Windows XP / MSVC.NET 2005
79 | \i Qt 4.4, 4.5 / Linux / gcc
80 | \i Qt 4.4, 4.5 / MacOS X 10.5 / gcc
81 | \endlist
82 |
83 |
84 |
85 |
86 | */
87 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/qtservice.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE=subdirs
2 | CONFIG += ordered
3 | include(common.pri)
4 | qtservice-uselib:SUBDIRS=buildlib
5 | SUBDIRS+=examples
6 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/src/QtService:
--------------------------------------------------------------------------------
1 | #include "qtservice.h"
2 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/src/QtServiceBase:
--------------------------------------------------------------------------------
1 | #include "qtservice.h"
2 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/src/QtServiceController:
--------------------------------------------------------------------------------
1 | #include "qtservice.h"
2 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/src/qtservice.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #ifndef QTSERVICE_H
42 | #define QTSERVICE_H
43 |
44 | #include
45 |
46 | #if defined(Q_OS_WIN)
47 | # if !defined(QT_QTSERVICE_EXPORT) && !defined(QT_QTSERVICE_IMPORT)
48 | # define QT_QTSERVICE_EXPORT
49 | # elif defined(QT_QTSERVICE_IMPORT)
50 | # if defined(QT_QTSERVICE_EXPORT)
51 | # undef QT_QTSERVICE_EXPORT
52 | # endif
53 | # define QT_QTSERVICE_EXPORT __declspec(dllimport)
54 | # elif defined(QT_QTSERVICE_EXPORT)
55 | # undef QT_QTSERVICE_EXPORT
56 | # define QT_QTSERVICE_EXPORT __declspec(dllexport)
57 | # endif
58 | #else
59 | # define QT_QTSERVICE_EXPORT
60 | #endif
61 |
62 | class QStringList;
63 | class QtServiceControllerPrivate;
64 |
65 | class QT_QTSERVICE_EXPORT QtServiceController
66 | {
67 | Q_DECLARE_PRIVATE(QtServiceController)
68 | public:
69 | enum StartupType
70 | {
71 | AutoStartup = 0, ManualStartup
72 | };
73 |
74 | QtServiceController(const QString &name);
75 | virtual ~QtServiceController();
76 |
77 | bool isInstalled() const;
78 | bool isRunning() const;
79 |
80 | QString serviceName() const;
81 | QString serviceDescription() const;
82 | StartupType startupType() const;
83 | QString serviceFilePath() const;
84 |
85 | static bool install(const QString &serviceFilePath, const QString &account = QString(),
86 | const QString &password = QString());
87 | bool uninstall();
88 |
89 | bool start(const QStringList &arguments);
90 | bool start();
91 | bool stop();
92 | bool pause();
93 | bool resume();
94 | bool sendCommand(int code);
95 |
96 | private:
97 | QtServiceControllerPrivate *d_ptr;
98 | };
99 |
100 | class QtServiceBasePrivate;
101 |
102 | class QT_QTSERVICE_EXPORT QtServiceBase
103 | {
104 | Q_DECLARE_PRIVATE(QtServiceBase)
105 | public:
106 |
107 | enum MessageType
108 | {
109 | Success = 0, Error, Warning, Information
110 | };
111 |
112 | enum ServiceFlag
113 | {
114 | Default = 0x00,
115 | CanBeSuspended = 0x01,
116 | CannotBeStopped = 0x02,
117 | NeedsStopOnShutdown = 0x04
118 | };
119 |
120 | Q_DECLARE_FLAGS(ServiceFlags, ServiceFlag)
121 |
122 | QtServiceBase(int argc, char **argv, const QString &name);
123 | virtual ~QtServiceBase();
124 |
125 | QString serviceName() const;
126 |
127 | QString serviceDescription() const;
128 | void setServiceDescription(const QString &description);
129 |
130 | QtServiceController::StartupType startupType() const;
131 | void setStartupType(QtServiceController::StartupType startupType);
132 |
133 | ServiceFlags serviceFlags() const;
134 | void setServiceFlags(ServiceFlags flags);
135 |
136 | int exec();
137 |
138 | void logMessage(const QString &message, MessageType type = Success,
139 | int id = 0, uint category = 0, const QByteArray &data = QByteArray());
140 |
141 | static QtServiceBase *instance();
142 |
143 | protected:
144 |
145 | virtual void start() = 0;
146 | virtual void stop();
147 | virtual void pause();
148 | virtual void resume();
149 | virtual void processCommand(int code);
150 |
151 | virtual void createApplication(int &argc, char **argv) = 0;
152 |
153 | virtual int executeApplication() = 0;
154 |
155 | private:
156 |
157 | friend class QtServiceSysPrivate;
158 | QtServiceBasePrivate *d_ptr;
159 | };
160 |
161 | template
162 | class QtService : public QtServiceBase
163 | {
164 | public:
165 | QtService(int argc, char **argv, const QString &name)
166 | : QtServiceBase(argc, argv, name), app(0)
167 | { }
168 | ~QtService()
169 | {
170 | }
171 |
172 | protected:
173 | Application *application() const
174 | { return app; }
175 |
176 | virtual void createApplication(int &argc, char **argv)
177 | {
178 | app = new Application(argc, argv);
179 | QCoreApplication *a = app;
180 | Q_UNUSED(a);
181 | }
182 |
183 | virtual int executeApplication()
184 | { return Application::exec(); }
185 |
186 | private:
187 | Application *app;
188 | };
189 |
190 | Q_DECLARE_OPERATORS_FOR_FLAGS(QtServiceBase::ServiceFlags)
191 |
192 | #endif // QTSERVICE_H
193 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/src/qtservice.pri:
--------------------------------------------------------------------------------
1 | include(../common.pri)
2 | INCLUDEPATH += $$PWD
3 | DEPENDPATH += $$PWD
4 | !win32:QT += network
5 | win32:LIBS += -luser32
6 |
7 | qtservice-uselib:!qtservice-buildlib {
8 | LIBS += -L$$QTSERVICE_LIBDIR -l$$QTSERVICE_LIBNAME
9 | } else {
10 | HEADERS += $$PWD/qtservice.h \
11 | $$PWD/qtservice_p.h
12 | SOURCES += $$PWD/qtservice.cpp
13 | win32:SOURCES += $$PWD/qtservice_win.cpp
14 | unix:HEADERS += $$PWD/qtunixsocket.h $$PWD/qtunixserversocket.h
15 | unix:SOURCES += $$PWD/qtservice_unix.cpp $$PWD/qtunixsocket.cpp $$PWD/qtunixserversocket.cpp
16 | }
17 |
18 | win32 {
19 | qtservice-buildlib:shared:DEFINES += QT_QTSERVICE_EXPORT
20 | else:qtservice-uselib:DEFINES += QT_QTSERVICE_IMPORT
21 | }
22 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/src/qtservice_p.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #ifndef QTSERVICE_P_H
42 | #define QTSERVICE_P_H
43 |
44 | #include
45 | #include "qtservice.h"
46 |
47 | class QtServiceControllerPrivate
48 | {
49 | Q_DECLARE_PUBLIC(QtServiceController)
50 | public:
51 | QString serviceName;
52 | QtServiceController *q_ptr;
53 | };
54 |
55 | class QtServiceBasePrivate
56 | {
57 | Q_DECLARE_PUBLIC(QtServiceBase)
58 | public:
59 |
60 | QtServiceBasePrivate(const QString &name);
61 | ~QtServiceBasePrivate();
62 |
63 | QtServiceBase *q_ptr;
64 |
65 | QString serviceDescription;
66 | QtServiceController::StartupType startupType;
67 | QtServiceBase::ServiceFlags serviceFlags;
68 | QStringList args;
69 |
70 | static class QtServiceBase *instance;
71 |
72 | QtServiceController controller;
73 |
74 | void startService();
75 | int run(bool asService, const QStringList &argList);
76 | bool install(const QString &account, const QString &password);
77 |
78 | bool start();
79 |
80 | QString filePath() const;
81 | bool sysInit();
82 | void sysSetPath();
83 | void sysCleanup();
84 | class QtServiceSysPrivate *sysd;
85 | };
86 |
87 | #endif
88 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/src/qtunixserversocket.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #include "qtunixserversocket.h"
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 |
48 | #ifndef SUN_LEN
49 | #define SUN_LEN(ptr) ((size_t)(((struct sockaddr_un *) 0)->sun_path) \
50 | +strlen ((ptr)->sun_path))
51 | #endif
52 |
53 | QtUnixServerSocket::QtUnixServerSocket(const QString &path, QObject *parent)
54 | : QTcpServer(parent)
55 | {
56 | setPath(path);
57 | }
58 |
59 | QtUnixServerSocket::QtUnixServerSocket(QObject *parent)
60 | : QTcpServer(parent)
61 | {
62 | }
63 |
64 | void QtUnixServerSocket::setPath(const QString &path)
65 | {
66 | path_.clear();
67 |
68 | int sock = ::socket(PF_UNIX, SOCK_STREAM, 0);
69 | if (sock != -1) {
70 | struct sockaddr_un addr;
71 | ::memset(&addr, 0, sizeof(struct sockaddr_un));
72 | addr.sun_family = AF_UNIX;
73 | ::unlink(path.toLatin1().constData()); // ### This might need to be changed
74 | unsigned int pathlen = strlen(path.toLatin1().constData());
75 | if (pathlen > sizeof(addr.sun_path)) pathlen = sizeof(addr.sun_path);
76 | ::memcpy(addr.sun_path, path.toLatin1().constData(), pathlen);
77 | if ((::bind(sock, (struct sockaddr *)&addr, SUN_LEN(&addr)) != -1) &&
78 | (::listen(sock, 5) != -1)) {
79 | setSocketDescriptor(sock);
80 | path_ = path;
81 | }
82 | }
83 | }
84 |
85 | void QtUnixServerSocket::close()
86 | {
87 | QTcpServer::close();
88 | if (!path_.isEmpty()) {
89 | ::unlink(path_.toLatin1().constData());
90 | path_.clear();
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/src/qtunixserversocket.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #ifndef QTUNIXSERVERSOCKET_H
42 | #define QTUNIXSERVERSOCKET_H
43 |
44 | #include
45 |
46 | class QtUnixServerSocket : public QTcpServer
47 | {
48 | Q_OBJECT
49 | public:
50 | QtUnixServerSocket(const QString &path, QObject *parent = 0);
51 | QtUnixServerSocket(QObject *parent = 0);
52 |
53 | void setPath(const QString &path);
54 | void close();
55 |
56 | private:
57 | QString path_;
58 | };
59 |
60 |
61 | #endif
62 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/src/qtunixsocket.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #include "qtunixsocket.h"
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 |
48 | #ifndef SUN_LEN
49 | #define SUN_LEN(ptr) ((size_t)(((struct sockaddr_un *) 0)->sun_path) \
50 | +strlen ((ptr)->sun_path))
51 | #endif
52 |
53 | QtUnixSocket::QtUnixSocket(QObject *parent)
54 | : QTcpSocket(parent)
55 | {
56 | }
57 |
58 | bool QtUnixSocket::connectTo(const QString &path)
59 | {
60 | bool ret = false;
61 | int sock = ::socket(PF_UNIX, SOCK_STREAM, 0);
62 | if (sock != -1) {
63 | struct sockaddr_un addr;
64 | ::memset(&addr, 0, sizeof(struct sockaddr_un));
65 | addr.sun_family = AF_UNIX;
66 | size_t pathlen = strlen(path.toLatin1().constData());
67 | pathlen = qMin(pathlen, sizeof(addr.sun_path));
68 | ::memcpy(addr.sun_path, path.toLatin1().constData(), pathlen);
69 | int err = ::connect(sock, (struct sockaddr *)&addr, SUN_LEN(&addr));
70 | if (err != -1) {
71 | setSocketDescriptor(sock);
72 | ret = true;
73 | } else {
74 | ::close(sock);
75 | }
76 | }
77 | return ret;
78 | }
79 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestQtService/qtservice/src/qtunixsocket.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #ifndef QTUNIXSOCKET_H
42 | #define QTUNIXSOCKET_H
43 |
44 | #include
45 |
46 | class QtUnixSocket : public QTcpSocket
47 | {
48 | Q_OBJECT
49 | public:
50 | QtUnixSocket(QObject *parent = 0);
51 |
52 | bool connectTo(const QString &path);
53 | };
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestSignalTrigger.pri:
--------------------------------------------------------------------------------
1 | DESTDIR = $$PWD/build
2 |
--------------------------------------------------------------------------------
/TestSignalTrigger/TestSignalTrigger.pro:
--------------------------------------------------------------------------------
1 | TEMPLATE = subdirs
2 |
3 | SUBDIRS += \
4 | TestQtService \
5 | PluginOne \
6 | PluginTwo \
7 | TestPluginOnePluginTwo
8 |
9 | TestPluginOnePluginTwo.depends = \
10 | PluginOne \
11 | PluginTwo
12 |
13 | TestQtService.depends = \
14 | PluginOne \
15 | PluginTwo
16 |
--------------------------------------------------------------------------------
/TestWindowsService/.gitignore:
--------------------------------------------------------------------------------
1 | *.pro.user
2 | build
3 |
--------------------------------------------------------------------------------
/TestWindowsService/README.txt:
--------------------------------------------------------------------------------
1 | # MyWindowsService
2 | This is a Windows Service or Unix Daemon. It monitors users' log on/log off, lock/unlock, sleep/awake Windows events, and writes to the log.
3 | The log locates at C:/ProgramData/MyWindowsService/mws.log.
4 | This project also gives several tries to get the specific user's (the active user's) user name and environment variable.
5 | It seems the user name of the active user can be got, but it's hard to get the environment variables.
6 |
--------------------------------------------------------------------------------
/TestWindowsService/TestWindowsService.pri:
--------------------------------------------------------------------------------
1 | PROJ_ARCH = "Unknown";
2 |
3 | equals(QT_ARCH, x86_64) {
4 | PROJ_ARCH = "x64"
5 | } else : equals(QT_ARCH, i386) {
6 | PROJ_ARCH = "x86"
7 | }
8 |
9 | CONFIG(debug, debug|release) {
10 | PROJ_SPEC = $$basename(QMAKESPEC)-$${PROJ_ARCH}-d
11 | } else {
12 | PROJ_SPEC = $$basename(QMAKESPEC)-$${PROJ_ARCH}-r
13 | }
14 |
15 | DependencyPath = "release"
16 | CONFIG(debug, debug|release) {
17 | DependencyPath = "debug"
18 | } else {
19 | DependencyPath = "release"
20 | }
21 |
22 | defineTest(copyDependency) {
23 | QMAKE_POST_LINK += $(COPY_FILE) \
24 | $$system_quote($$shell_path($$PWD/qt-service-lib/$$DependencyPath/*.dll)) \
25 | $$system_quote($$shell_path($$DESTDIR)) $$escape_expand(\\n\\t)
26 |
27 | export(QMAKE_POST_LINK)
28 | }
29 |
--------------------------------------------------------------------------------
/TestWindowsService/TestWindowsService.pro:
--------------------------------------------------------------------------------
1 | include(TestWindowsService.pri)
2 |
3 | QT += core
4 | QT -= gui
5 |
6 |
7 | TARGET = TestWindowsService
8 | TEMPLATE = app
9 |
10 | DESTDIR = $$PWD/build/$$PROJ_SPEC
11 |
12 | DEFINES += _UNICODE
13 |
14 | CONFIG += c++11 \
15 | console
16 | CONFIG -= app_bundle
17 |
18 | CONFIG(debug, debug|release) {
19 | LIBS += -L$$PWD/qt-service-lib/debug \
20 | -lQtSolutions_Service-headd
21 | } else {
22 | LIBS += -L$$PWD/qt-service-lib/release \
23 | -lQtSolutions_Service-head
24 | }
25 |
26 | LIBS += -ladvapi32 \
27 | -lkernel32 \
28 | -lWtsapi32 \
29 | -lUser32 \
30 | -lUserEnv
31 |
32 | INCLUDEPATH += $$PWD/qt-service-lib/include
33 |
34 | SOURCES += main.cpp \
35 | my_windows_service.cpp \
36 | message_handler.cpp \
37 | windowassist.cpp
38 |
39 | HEADERS += \
40 | my_windows_service.h \
41 | qt-service-lib/include/qtservice.h \
42 | message_handler.h \
43 | windowassist.h
44 |
45 | DISTFILES += \
46 | TestWindowsService.pri
47 |
48 | copyDependency()
49 |
--------------------------------------------------------------------------------
/TestWindowsService/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "message_handler.h"
4 | #include "my_windows_service.h"
5 |
6 | #include
7 |
8 | int main(int argc, char *argv[])
9 | {
10 | MyWindowsService service(argc, argv);
11 |
12 | qInfo() << "In the main function for MyWindowsService...";
13 |
14 | return service.exec();
15 | }
16 |
--------------------------------------------------------------------------------
/TestWindowsService/message_handler.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "message_handler.h"
9 |
10 | using namespace message_handler;
11 |
12 |
13 | QString MessageHandler::s_log = "mws.log";
14 |
15 |
16 | void MessageHandler::setLogFile(QString file)
17 | {
18 | s_log = file;
19 | }
20 |
21 |
22 | void MessageHandler::FormatMessage(QtMsgType type, const QMessageLogContext &context, const QString &msg)
23 | {
24 | static QMutex mutex;
25 | mutex.lock();
26 |
27 | QFile logFile(MessageHandler::s_log);
28 | logFile.open(QIODevice::WriteOnly | QIODevice::Append);
29 |
30 | QString log("");
31 | log += QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz") + QString(" ");
32 |
33 | switch(type)
34 | {
35 | case QtDebugMsg:
36 | log += QString("[Debug]");
37 | break;
38 |
39 | case QtInfoMsg:
40 | log += QString("[Info]");
41 | break;
42 |
43 | case QtWarningMsg:
44 | log += QString("[Warn]");
45 | break;
46 |
47 | case QtCriticalMsg:
48 | log += QString("[Critical]");
49 | break;
50 |
51 | case QtFatalMsg:
52 | log += QString("[Fatal]");
53 | abort();
54 | break;
55 |
56 | default:
57 | log += QString("[UnknownLogType]");
58 | break;
59 | };
60 |
61 | log += QString(context.file)
62 | + QString(", Line ")
63 | + QString::number(context.line)
64 | + QString(": %1\n").arg(msg);
65 |
66 | QTextStream text_stream(&logFile);
67 | text_stream << log;
68 | logFile.flush();
69 | logFile.close();
70 |
71 | mutex.unlock();
72 | }
73 |
--------------------------------------------------------------------------------
/TestWindowsService/message_handler.h:
--------------------------------------------------------------------------------
1 | #ifndef MESSAGEHANDLER_H
2 | #define MESSAGEHANDLER_H
3 |
4 | #include
5 |
6 | namespace message_handler {
7 | class MessageHandler
8 | {
9 | private:
10 | MessageHandler();
11 | ~MessageHandler();
12 |
13 | public:
14 | static void setLogFile(QString file = "./mws.log");
15 | static void FormatMessage(QtMsgType type , const QMessageLogContext& context , const QString& msg);
16 |
17 | private:
18 | static QString s_log;
19 | };
20 | }
21 |
22 |
23 | #endif // MESSAGEHANDLER_H
24 |
--------------------------------------------------------------------------------
/TestWindowsService/my_windows_service.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "message_handler.h"
6 | #include "my_windows_service.h"
7 |
8 | #include
9 |
10 |
11 | MyWindowsService::MyWindowsService(int argc, char** argv)
12 | : QtService(argc, argv, "My Windows Service")
13 | {
14 | setServiceDescription("This is my Windows Service");
15 | setServiceFlags(QtServiceBase::CanBeSuspended);
16 |
17 | m_windowAssist = new WindowAssist(this);
18 | }
19 |
20 |
21 | void MyWindowsService::installMessageHandler()
22 | {
23 | // Install Message Handler
24 | QString logDirName = "C:/ProgramData/MyWindowsService";
25 | QDir logDir(logDirName);
26 |
27 | if (!logDir.exists())
28 | {
29 | qDebug() << "Creating folder: " << logDirName;
30 | QDir().mkdir(logDirName);
31 | }
32 |
33 | QString logFile = logDirName + "/mws.log";
34 |
35 | // Remove the Macro defined in winbase.h
36 | #ifdef FormatMessage
37 | #undef FormatMessage
38 | message_handler::MessageHandler::setLogFile(logFile);
39 | qInstallMessageHandler(message_handler::MessageHandler::FormatMessage);
40 | #endif
41 | }
42 |
43 |
44 | void MyWindowsService::way1_GetUserNameByQT()
45 | {
46 | // In the system level process/service,
47 | // the UserName is "$", e.g. "FINIX-LAPTOP$".
48 |
49 | qInfo() << "Way 1 - Get User Name via QT...";
50 | qInfo() << "User Name = " << qgetenv("UserName");
51 | qInfo() << "---------------------------";
52 | }
53 |
54 |
55 | void MyWindowsService::way2_GetUserNameByWindowsAPI()
56 | {
57 | #ifdef Q_OS_WIN
58 | // Output: Windows User Name = "SYSTEM"
59 |
60 | qInfo() << "Way 2 - Get User Name via Windows API GetUserName()...";
61 |
62 | wchar_t acUserName[200];
63 | DWORD nUserName = sizeof(acUserName);
64 | if (GetUserName(acUserName, &nUserName))
65 | {
66 | // Translate wchar_t * to QString
67 | qInfo() << "Windows User Name = " << QString::fromWCharArray(acUserName);
68 | }
69 | #elif Q_OS_UNIX
70 | QCoreApplication coreApplication(argc, argv);
71 | QProcess process;
72 | QObject::connect(&process, &QProcess::finished, [&coreApplication, &process](int exitCode, QProcess::ExitStatus exitStatus) {
73 | qDebug() << process.readAllStandardOutput();
74 | coreApplication.quit();
75 | });
76 | process.start("whoami");
77 | #endif
78 | qInfo() << "---------------------------";
79 | }
80 |
81 |
82 |
83 | void MyWindowsService::way3_GetActiveUserNameByWindowsAPIInSystemProcess()
84 | {
85 | // Output: Windows User Name = "Finix"
86 |
87 | qInfo() << "Way 3 - Get Active User Name from a system process...";
88 | DWORD sessionId = WTSGetActiveConsoleSessionId();
89 | qInfo() << "session id = " << sessionId;
90 |
91 | wchar_t* ppBuffer[100];
92 | DWORD bufferSize;
93 | WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSUserName, ppBuffer, &bufferSize);
94 | qInfo() << "Windows User Name = " << QString::fromWCharArray(*ppBuffer);
95 |
96 | qInfo() << "---------------------------";
97 | }
98 |
99 |
100 | void MyWindowsService::way4_GetHomeLocationByQStandardPaths()
101 | {
102 | // Output: "C:/Windows/system32/config/systemprofile"
103 |
104 | qInfo() << "Way 4 - Get Home Location via QStandardPaths...";
105 | QStringList homePath = QStandardPaths::standardLocations(QStandardPaths::HomeLocation);
106 | qInfo() << homePath.first().split(QDir::separator()).last();
107 | qInfo() << "---------------------------";
108 | }
109 |
110 |
111 | void MyWindowsService::way5_GetHomeLocationByWindowsAPI()
112 | {
113 | // Output: "C:\\Windows\\system32\\config\\systemprofile"
114 |
115 | qInfo() << "Way 5 - Get Home Location via Windows API...";
116 | wchar_t envVar[] = L"UserProfile";
117 | wchar_t result[100];
118 | GetEnvironmentVariable(envVar, result, sizeof(result)/sizeof(wchar_t));
119 | qInfo() << "USER PROFILE = " << QString::fromWCharArray(result);
120 | qInfo() << "---------------------------";
121 | }
122 |
123 |
124 | void MyWindowsService::way6_GetHomeLoactioneByWTS()
125 | {
126 | qInfo() << "Way 6 - Get Home Location via WTS technique...";
127 | DWORD sessionId = WTSGetActiveConsoleSessionId();
128 | qInfo() << "Session ID = " << sessionId;
129 | wchar_t* ppBuffer[100];
130 | DWORD bufferSize;
131 |
132 | WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSWorkingDirectory, ppBuffer, &bufferSize);
133 | qInfo() << "Working Directory = " << QString::fromWCharArray(*ppBuffer); // Empty ""
134 |
135 | WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSClientDirectory, ppBuffer, &bufferSize);
136 | qInfo() << "Client Directory = " << QString::fromWCharArray(*ppBuffer); // Empty ""
137 |
138 | qInfo() << "---------------------------";
139 | }
140 |
141 | void MyWindowsService::way7_GetEnvironmentVariables()
142 | {
143 | qInfo() << "Way 7 - Get Environment Variables by Windows API CreateEnvironmentBlock()...";
144 |
145 | DWORD sessionId = WTSGetActiveConsoleSessionId();
146 | qInfo() << "Session ID = " << sessionId;
147 |
148 | HANDLE token;
149 | if (!WTSQueryUserToken(sessionId, &token))
150 | {
151 | qCritical() << "Failed to get the user token of session " << sessionId;
152 | qInfo() << "---------------------------";
153 | return;
154 | }
155 |
156 | wchar_t* pEnv = NULL;
157 | if (CreateEnvironmentBlock((void**)&pEnv, token, TRUE))
158 | {
159 | while (*pEnv) {
160 | // printf("%ls\n", pEnv);
161 | qInfo() << QString::fromWCharArray(pEnv);
162 | pEnv += wcslen(pEnv) + 1;
163 | }
164 | }
165 |
166 | qInfo() << "---------------------------";
167 | }
168 |
169 | static LONG GetStringRegKey(HKEY hKey, const std::wstring &strValueName, std::wstring &strValue, const std::wstring &strDefaultValue)
170 | {
171 | strValue = strDefaultValue;
172 | WCHAR szBuffer[512];
173 | DWORD dwBufferSize = sizeof(szBuffer);
174 | ULONG nError;
175 | nError = RegQueryValueExW(hKey, strValueName.c_str(), 0, NULL, (LPBYTE)szBuffer, &dwBufferSize);
176 | if (ERROR_SUCCESS == nError)
177 | {
178 | strValue = szBuffer;
179 | }
180 | return nError;
181 | }
182 |
183 | static void GetUserRegistryHive()
184 | {
185 | std::wstring strValueOfBinDir = L"Unknown Value";
186 | LONG regOpenResult = ERROR_SUCCESS;
187 |
188 | HKEY hKey;
189 |
190 | regOpenResult = RegOpenCurrentUser(KEY_READ, &hKey);
191 | if (regOpenResult != ERROR_SUCCESS)
192 | {
193 | qCritical() << "Failed to call RegOpenCurrentUser(), Error is " << regOpenResult;
194 | }
195 |
196 | HKEY hSubKey;
197 |
198 | RegOpenKeyEx(hKey,
199 | TEXT("Software\\Baidu\\BaiduYunGuanjia"),
200 | 0,
201 | KEY_READ,
202 | &hSubKey);
203 | GetStringRegKey(hSubKey, TEXT("installDir"), strValueOfBinDir, TEXT("Unknown"));
204 |
205 | qInfo() << "The value of Registry is " << QString::fromWCharArray( strValueOfBinDir.c_str() );
206 |
207 | }
208 |
209 | void MyWindowsService::way8_GetUserRegistry()
210 | {
211 | #ifdef Q_OS_WIN
212 |
213 | DWORD sessionId = WTSGetActiveConsoleSessionId();
214 | qInfo() << "Session ID = " << sessionId;
215 |
216 | wchar_t * ppUserName[100];
217 | DWORD sizeOfUserName;
218 | WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSUserName, ppUserName, &sizeOfUserName);
219 | qInfo() << "Windows User Name = " << QString::fromWCharArray(*ppUserName);
220 |
221 | std::wstring strValueOfBinDir = L"Unknown Value";
222 | LONG regOpenResult = ERROR_SUCCESS;
223 |
224 | HANDLE hUserToken = NULL;
225 | HANDLE hFakeToken = NULL;
226 |
227 | if (WTSQueryUserToken(sessionId, &hUserToken))
228 | {
229 | if (DuplicateTokenEx(hUserToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, 0, SecurityImpersonation, TokenPrimary, &hFakeToken) == TRUE)
230 | {
231 | qInfo() << "Before ImpersonateLoggedOnUser()......";
232 | if (ImpersonateLoggedOnUser(hFakeToken))
233 | {
234 | HKEY hKey;
235 |
236 | regOpenResult = RegOpenCurrentUser(KEY_READ, &hKey);
237 | if (regOpenResult != ERROR_SUCCESS)
238 | {
239 | qCritical() << "Failed to call RegOpenCurrentUser(), Error is " << regOpenResult;
240 | }
241 |
242 | HKEY hSubKey;
243 |
244 | RegOpenKeyEx(hKey,
245 | TEXT("Software\\Baidu\\BaiduYunGuanjia"),
246 | 0,
247 | KEY_READ,
248 | &hSubKey);
249 | GetStringRegKey(hSubKey, TEXT("installDir"), strValueOfBinDir, TEXT("Unknown"));
250 |
251 | RevertToSelf();
252 | }
253 | else
254 | {
255 | qCritical() << "Failed to ImpersonateLoggedOnUser...";
256 | }
257 | CloseHandle(hFakeToken);
258 | }
259 | else
260 | {
261 | qCritical() << "Failed to call DuplicateTokenEx...";
262 | }
263 | CloseHandle(hUserToken);
264 | }
265 | else
266 | {
267 | qCritical() << "Failed to get the user token of session " << sessionId;
268 | }
269 |
270 | qInfo() << "The value of Registry is " << QString::fromWCharArray( strValueOfBinDir.c_str() );
271 |
272 | // Check that after Impersonating, can get the User Registry hive or not. As expected, not.
273 | GetUserRegistryHive();
274 |
275 | #endif
276 | }
277 |
278 | void MyWindowsService::testUserStuff()
279 | {
280 | way1_GetUserNameByQT();
281 | way2_GetUserNameByWindowsAPI();
282 | way3_GetActiveUserNameByWindowsAPIInSystemProcess();
283 | way4_GetHomeLocationByQStandardPaths();
284 | way5_GetHomeLocationByWindowsAPI();
285 | way6_GetHomeLoactioneByWTS();
286 | way7_GetEnvironmentVariables();
287 | way8_GetUserRegistry();
288 | }
289 |
290 | void MyWindowsService::testKeepProcess()
291 | {
292 | QProcess* p = new QProcess(); // leaking on pourpose
293 | p->setProcessChannelMode(QProcess::MergedChannels);
294 |
295 | QObject::connect(p, &QProcess::started, [] () {
296 | qDebug() << "Notepad.exe started!";
297 | });
298 |
299 | // Keep restarting if notepad.exe is finished
300 | QObject::connect(p, static_cast(&QProcess::finished),
301 | [p] (int exitCode, QProcess::ExitStatus exitStatus) {
302 | qWarning() << "Notepad.exe was terminated! "
303 | << "Exit code: " << exitCode
304 | << "Exit status: " << exitStatus;
305 |
306 | // restart
307 | qWarning() << "Notepad.exe will restart... ";
308 | p->start();
309 | });
310 |
311 | p->start("notepad.exe");
312 | }
313 |
314 |
315 | void MyWindowsService::start()
316 | {
317 | // Only for "-e" option, as message handler has not been installed
318 | qDebug() << "Get into start().......";
319 |
320 | installMessageHandler();
321 |
322 | qInfo() << "Start MyWindowsService...";
323 |
324 | // testUserStuff();
325 |
326 | testKeepProcess(); // Keep restarting "notepad.exe" in case found that it is finished.
327 | }
328 |
329 | void MyWindowsService::stop()
330 | {
331 | qInfo() << "Stop MyWindowsService...";
332 | }
333 |
334 | void MyWindowsService::resume()
335 | {
336 | qInfo() << "Resume MyWindowsService...";
337 | }
338 |
339 | void MyWindowsService::pause()
340 | {
341 | qInfo() << "Pause MyWindowsService...";
342 | }
343 |
--------------------------------------------------------------------------------
/TestWindowsService/my_windows_service.h:
--------------------------------------------------------------------------------
1 | #ifndef MYWINDOWSSERVICE_H
2 | #define MYWINDOWSSERVICE_H
3 |
4 | #include "qtservice.h"
5 | #include "windowassist.h"
6 |
7 | #ifdef Q_OS_WIN
8 | #include
9 | #include
10 | #include
11 | #include
12 | #endif
13 |
14 | class MyWindowsService: public QtService, public QObject
15 | {
16 | public:
17 | MyWindowsService(int argc, char* argv[]);
18 |
19 | protected:
20 | void start();
21 | void pause();
22 | void resume();
23 | void stop();
24 |
25 | private:
26 | void installMessageHandler();
27 |
28 | void way1_GetUserNameByQT();
29 | void way2_GetUserNameByWindowsAPI();
30 | void way3_GetActiveUserNameByWindowsAPIInSystemProcess();
31 | void way4_GetHomeLocationByQStandardPaths();
32 | void way5_GetHomeLocationByWindowsAPI();
33 | void way6_GetHomeLoactioneByWTS();
34 | void way7_GetEnvironmentVariables();
35 | void way8_GetUserRegistry();
36 | void testUserStuff();
37 |
38 | void testKeepProcess();
39 |
40 | private:
41 | WindowAssist* m_windowAssist;
42 | };
43 |
44 | #endif // MYWINDOWSSERVICE_H
45 |
--------------------------------------------------------------------------------
/TestWindowsService/qt-service-lib/debug/QtSolutions_Service-headd.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FinixLei/QtProjects/8092222c35a70ca37d8f9a99f91cf925ffa8253c/TestWindowsService/qt-service-lib/debug/QtSolutions_Service-headd.dll
--------------------------------------------------------------------------------
/TestWindowsService/qt-service-lib/debug/QtSolutions_Service-headd.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FinixLei/QtProjects/8092222c35a70ca37d8f9a99f91cf925ffa8253c/TestWindowsService/qt-service-lib/debug/QtSolutions_Service-headd.lib
--------------------------------------------------------------------------------
/TestWindowsService/qt-service-lib/debug/qtsolutions_service-headd.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FinixLei/QtProjects/8092222c35a70ca37d8f9a99f91cf925ffa8253c/TestWindowsService/qt-service-lib/debug/qtsolutions_service-headd.pdb
--------------------------------------------------------------------------------
/TestWindowsService/qt-service-lib/include/qtservice.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #ifndef QTSERVICE_H
42 | #define QTSERVICE_H
43 |
44 | #include
45 |
46 | #if defined(Q_OS_WIN)
47 | # if !defined(QT_QTSERVICE_EXPORT) && !defined(QT_QTSERVICE_IMPORT)
48 | # define QT_QTSERVICE_EXPORT
49 | # elif defined(QT_QTSERVICE_IMPORT)
50 | # if defined(QT_QTSERVICE_EXPORT)
51 | # undef QT_QTSERVICE_EXPORT
52 | # endif
53 | # define QT_QTSERVICE_EXPORT __declspec(dllimport)
54 | # elif defined(QT_QTSERVICE_EXPORT)
55 | # undef QT_QTSERVICE_EXPORT
56 | # define QT_QTSERVICE_EXPORT __declspec(dllexport)
57 | # endif
58 | #else
59 | # define QT_QTSERVICE_EXPORT
60 | #endif
61 |
62 | class QStringList;
63 | class QtServiceControllerPrivate;
64 |
65 | class QT_QTSERVICE_EXPORT QtServiceController
66 | {
67 | Q_DECLARE_PRIVATE(QtServiceController)
68 | public:
69 | enum StartupType
70 | {
71 | AutoStartup = 0, ManualStartup
72 | };
73 |
74 | QtServiceController(const QString &name);
75 | virtual ~QtServiceController();
76 |
77 | bool isInstalled() const;
78 | bool isRunning() const;
79 |
80 | QString serviceName() const;
81 | QString serviceDescription() const;
82 | StartupType startupType() const;
83 | QString serviceFilePath() const;
84 |
85 | static bool install(const QString &serviceFilePath, const QString &account = QString(),
86 | const QString &password = QString());
87 | bool uninstall();
88 |
89 | bool start(const QStringList &arguments);
90 | bool start();
91 | bool stop();
92 | bool pause();
93 | bool resume();
94 | bool sendCommand(int code);
95 |
96 | private:
97 | QtServiceControllerPrivate *d_ptr;
98 | };
99 |
100 | class QtServiceBasePrivate;
101 |
102 | class QT_QTSERVICE_EXPORT QtServiceBase
103 | {
104 | Q_DECLARE_PRIVATE(QtServiceBase)
105 | public:
106 |
107 | enum MessageType
108 | {
109 | Success = 0, Error, Warning, Information
110 | };
111 |
112 | enum ServiceFlag
113 | {
114 | Default = 0x00,
115 | CanBeSuspended = 0x01,
116 | CannotBeStopped = 0x02,
117 | NeedsStopOnShutdown = 0x04
118 | };
119 |
120 | Q_DECLARE_FLAGS(ServiceFlags, ServiceFlag)
121 |
122 | QtServiceBase(int argc, char **argv, const QString &name);
123 | virtual ~QtServiceBase();
124 |
125 | QString serviceName() const;
126 |
127 | QString serviceDescription() const;
128 | void setServiceDescription(const QString &description);
129 |
130 | QtServiceController::StartupType startupType() const;
131 | void setStartupType(QtServiceController::StartupType startupType);
132 |
133 | ServiceFlags serviceFlags() const;
134 | void setServiceFlags(ServiceFlags flags);
135 |
136 | int exec();
137 |
138 | void logMessage(const QString &message, MessageType type = Success,
139 | int id = 0, uint category = 0, const QByteArray &data = QByteArray());
140 |
141 | static QtServiceBase *instance();
142 |
143 | protected:
144 |
145 | virtual void start() = 0;
146 | virtual void stop();
147 | virtual void pause();
148 | virtual void resume();
149 | virtual void processCommand(int code);
150 |
151 | virtual void createApplication(int &argc, char **argv) = 0;
152 |
153 | virtual int executeApplication() = 0;
154 |
155 | private:
156 |
157 | friend class QtServiceSysPrivate;
158 | QtServiceBasePrivate *d_ptr;
159 | };
160 |
161 | template
162 | class QtService : public QtServiceBase
163 | {
164 | public:
165 | QtService(int argc, char **argv, const QString &name)
166 | : QtServiceBase(argc, argv, name), app(0)
167 | { }
168 | ~QtService()
169 | {
170 | }
171 |
172 | protected:
173 | Application *application() const
174 | { return app; }
175 |
176 | virtual void createApplication(int &argc, char **argv)
177 | {
178 | app = new Application(argc, argv);
179 | QCoreApplication *a = app;
180 | Q_UNUSED(a);
181 | }
182 |
183 | virtual int executeApplication()
184 | { return Application::exec(); }
185 |
186 | private:
187 | Application *app;
188 | };
189 |
190 | Q_DECLARE_OPERATORS_FOR_FLAGS(QtServiceBase::ServiceFlags)
191 |
192 | #endif // QTSERVICE_H
193 |
--------------------------------------------------------------------------------
/TestWindowsService/qt-service-lib/release/QtSolutions_Service-head.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FinixLei/QtProjects/8092222c35a70ca37d8f9a99f91cf925ffa8253c/TestWindowsService/qt-service-lib/release/QtSolutions_Service-head.dll
--------------------------------------------------------------------------------
/TestWindowsService/qt-service-lib/release/QtSolutions_Service-head.lib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FinixLei/QtProjects/8092222c35a70ca37d8f9a99f91cf925ffa8253c/TestWindowsService/qt-service-lib/release/QtSolutions_Service-head.lib
--------------------------------------------------------------------------------
/TestWindowsService/windowassist.cpp:
--------------------------------------------------------------------------------
1 | #include "windowassist.h"
2 |
3 | #include
4 | #include
5 |
6 | #ifdef Q_OS_WIN
7 |
8 | #include "windows.h"
9 | #include "Wtsapi32.h"
10 |
11 |
12 | void GetActiveUserName()
13 | {
14 | DWORD sessionId = WTSGetActiveConsoleSessionId();
15 | qInfo() << "session id = " << sessionId;
16 |
17 | wchar_t* ppBuffer[100];
18 | DWORD bufferSize;
19 | WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionId, WTSUserName, ppBuffer, &bufferSize);
20 | qInfo() << "Windows User Name = " << QString::fromWCharArray(*ppBuffer);
21 | }
22 |
23 |
24 | class WindowAssistImpl
25 | {
26 | WindowAssistImpl() = delete;
27 |
28 | public:
29 | static LPCWSTR m_windowName;
30 | static HWND m_windowHandle;
31 | static WindowAssist* m_windowAssist;
32 |
33 | public:
34 | static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
35 | {
36 | switch (msg)
37 | {
38 | case WM_WTSSESSION_CHANGE:
39 | switch (wParam)
40 | {
41 | case WTS_SESSION_LOGON:
42 | if (m_windowAssist != nullptr)
43 | {
44 | qDebug() << "Capture user logon event.";
45 | emit m_windowAssist->logon();
46 |
47 | GetActiveUserName();
48 | }
49 | break;
50 | case WTS_SESSION_LOGOFF:
51 | if (m_windowAssist != nullptr)
52 | {
53 | qDebug() << "Capture user logoff event.";
54 | emit m_windowAssist->logoff();
55 | }
56 | break;
57 | case WTS_SESSION_LOCK:
58 | if (m_windowAssist != nullptr)
59 | {
60 | qDebug() << "Capture user lock event.";
61 | emit m_windowAssist->locked();
62 | }
63 | break;
64 | case WTS_SESSION_UNLOCK:
65 | if (m_windowAssist != nullptr)
66 | {
67 | qDebug() << "Capture user unlock event.";
68 | emit m_windowAssist->unlocked();
69 |
70 | GetActiveUserName();
71 | }
72 | break;
73 | }
74 | break;
75 | case WM_POWERBROADCAST:
76 | switch (wParam)
77 | {
78 | case PBT_APMSUSPEND:
79 | if (m_windowAssist != nullptr)
80 | {
81 | qDebug() << "Capture system sleep event.";
82 | emit m_windowAssist->sleep();
83 | }
84 | break;
85 | case PBT_APMRESUMEAUTOMATIC:
86 | if (m_windowAssist != nullptr)
87 | {
88 | qDebug() << "Capture system awake event.";
89 | emit m_windowAssist->awake();
90 | }
91 | break;
92 | }
93 | break;
94 | case WM_DESTROY:
95 | PostQuitMessage(0);
96 | return 0;
97 | }
98 |
99 | return DefWindowProc(hWnd, msg, wParam, lParam);
100 | }
101 |
102 | static void createWindow()
103 | {
104 | LPCWSTR name = m_windowName;
105 |
106 | HINSTANCE instance = GetModuleHandle(NULL);
107 |
108 | WNDCLASSEX wcex;
109 | wcex.cbSize = sizeof(WNDCLASSEX);
110 | wcex.style = CS_NOCLOSE;
111 | wcex.lpfnWndProc = &WindowAssistImpl::WndProc;
112 | wcex.cbClsExtra = 0;
113 | wcex.cbWndExtra = 0;
114 | wcex.hInstance = instance;
115 | wcex.hIcon = NULL;
116 | wcex.hCursor = NULL;
117 | wcex.hbrBackground = NULL;
118 | wcex.lpszMenuName = NULL;
119 | wcex.lpszClassName = m_windowName;
120 | wcex.hIconSm = NULL;
121 |
122 | if (FALSE == RegisterClassEx(&wcex))
123 | {
124 | qCritical() << "RegisterClassEx failed";
125 | return;
126 | }
127 |
128 | m_windowHandle = CreateWindowEx(
129 | WS_EX_NOACTIVATE,
130 | name,
131 | name,
132 | NULL,
133 | 0, 0, 0, 0,
134 | NULL,
135 | NULL,
136 | instance,
137 | NULL);
138 |
139 | if (m_windowHandle == NULL)
140 | {
141 | qCritical() << "CreateWindowEx failed";
142 | return;
143 | }
144 |
145 | if (!WTSRegisterSessionNotification(m_windowHandle, NOTIFY_FOR_ALL_SESSIONS))
146 | {
147 | qCritical() << "Register Session Notification failed";
148 | return;
149 | }
150 | }
151 |
152 | static void destroyWindow()
153 | {
154 | HINSTANCE instance = GetModuleHandle(NULL);
155 |
156 | if (FALSE == CloseWindow(m_windowHandle))
157 | {
158 | qDebug() << "CloseWindow failed";
159 | }
160 |
161 | if (FALSE == DestroyWindow(m_windowHandle))
162 | {
163 | qDebug() << "DestroyWindow failed";
164 | }
165 |
166 | if (FALSE == UnregisterClass(m_windowName, instance))
167 | {
168 | qDebug() << "UnregisterClass failed";
169 | }
170 |
171 | m_windowHandle = NULL;
172 | }
173 | };
174 |
175 | /**************************************************************************************************/
176 |
177 | LPCWSTR WindowAssistImpl::m_windowName = L"Event handler";
178 | HWND WindowAssistImpl::m_windowHandle = NULL;
179 | WindowAssist* WindowAssistImpl::m_windowAssist = nullptr;
180 |
181 | /**************************************************************************************************/
182 |
183 | WindowAssist::WindowAssist(QObject* parent)
184 | : QObject(parent)
185 | {
186 | WindowAssistImpl::m_windowAssist = this;
187 | WindowAssistImpl::createWindow();
188 | }
189 |
190 | /**************************************************************************************************/
191 |
192 | WindowAssist::~WindowAssist()
193 | {
194 | WindowAssistImpl::destroyWindow();
195 | WindowAssistImpl::m_windowAssist = nullptr;
196 | }
197 |
198 | /**************************************************************************************************/
199 |
200 | #endif // Q_OS_WIN
201 |
--------------------------------------------------------------------------------
/TestWindowsService/windowassist.h:
--------------------------------------------------------------------------------
1 | #ifndef WINDOWASSIST_H
2 | #define WINDOWASSIST_H
3 |
4 | #include
5 |
6 | class WindowAssist: public QObject
7 | {
8 | Q_OBJECT
9 |
10 | public:
11 | /*! \brief Creates the instance of WindowAssist. */
12 | explicit WindowAssist(QObject* parent = nullptr);
13 |
14 | /*! \brief Destroys the instance of WindowAssist. */
15 | virtual ~WindowAssist();
16 |
17 | Q_SIGNALS:
18 |
19 | /*! \brief Signal emited whenever the user logon system.
20 | * \details Signal emited whenever the user logon system.
21 | */
22 | void logon();
23 |
24 | /*! \brief Signal emited whenever the user logoff system.
25 | * \details Signal emited whenever the user logoff system.
26 | */
27 | void logoff();
28 |
29 | /*! \brief Signal emited whenever the user lock system.
30 | * \details Signal emited whenever the user lock system.
31 | */
32 | void locked();
33 |
34 | /*! \brief Signal emited whenever the user unlock system.
35 | * \details Signal emited whenever the user unlock system.
36 | */
37 | void unlocked();
38 |
39 | /*! \brief Signal emited whenever the computer goes to sleep.
40 | * \details Signal emited whenever the computer goes to sleep.
41 | */
42 | void sleep();
43 |
44 | /*! \brief Signal emited whenever the computer wakes up after sleep.
45 | * \details Signal emited whenever the computer wakes up after sleep.
46 | */
47 | void awake();
48 | };
49 |
50 | #endif // WINDOWASSIST_H
51 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/TestWindowsServiceWithLibrarySource.pri:
--------------------------------------------------------------------------------
1 | PROJ_ARCH = "Unknown";
2 |
3 | equals(QT_ARCH, x86_64) {
4 | PROJ_ARCH = "x64"
5 | } else : equals(QT_ARCH, i386) {
6 | PROJ_ARCH = "x86"
7 | }
8 |
9 | CONFIG(debug, debug|release) {
10 | PROJ_SPEC = $$basename(QMAKESPEC)-$${PROJ_ARCH}-d
11 | } else {
12 | PROJ_SPEC = $$basename(QMAKESPEC)-$${PROJ_ARCH}-r
13 | }
14 |
15 | DependencyPath = "release"
16 | CONFIG(debug, debug|release) {
17 | DependencyPath = "debug"
18 | } else {
19 | DependencyPath = "release"
20 | }
21 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/TestWindowsServiceWithLibrarySource.pro:
--------------------------------------------------------------------------------
1 | include(TestWindowsServiceWithLibrarySource.pri)
2 | include(qtservice/qtservice.pri)
3 |
4 | QT += core
5 | QT -= gui
6 |
7 | CONFIG += c++11
8 |
9 | TARGET = my_windows_service
10 | CONFIG += console
11 | CONFIG -= app_bundle
12 | CONFIG += c++11
13 |
14 | TEMPLATE = app
15 |
16 | DESTDIR = $$PWD/build/$$PROJ_SPEC
17 |
18 | SOURCES += main.cpp \
19 | my_windows_service.cpp
20 |
21 | HEADERS += my_windows_service.h
22 |
23 | DISTFILES += \
24 | qtservice/qtservice.pri \
25 | TestWindowsServiceWithLibrarySource.pri
26 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include "my_windows_service.h"
4 |
5 | int main(int argc, char *argv[])
6 | {
7 | MyWindowsService service(argc, argv);
8 |
9 | return service.exec();
10 | }
11 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/my_windows_service.cpp:
--------------------------------------------------------------------------------
1 | #include "my_windows_service.h"
2 |
3 | MyWindowsService::MyWindowsService(int argc, char* argv[])
4 | : QtService(argc, argv, "My Windows Service with Source")
5 | {
6 | }
7 |
8 | void MyWindowsService::start()
9 | {
10 | }
11 |
12 | void MyWindowsService::stop()
13 | {
14 | }
15 |
16 | void MyWindowsService::pause()
17 | {
18 | }
19 |
20 | void MyWindowsService::resume()
21 | {
22 | }
23 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/my_windows_service.h:
--------------------------------------------------------------------------------
1 | #ifndef MYWINDOWSSERVICE_H
2 | #define MYWINDOWSSERVICE_H
3 |
4 | #include "qtservice.h"
5 |
6 |
7 | class MyWindowsService: public QtService
8 | {
9 | public:
10 | MyWindowsService(int argc, char* argv[]);
11 | ~MyWindowsService(){}
12 |
13 | public:
14 | void start();
15 | void pause();
16 | void resume();
17 | void stop();
18 | };
19 |
20 | #endif // MYWINDOWSSERVICE_H
21 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/qtservice/qtservice.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #ifndef QTSERVICE_H
42 | #define QTSERVICE_H
43 |
44 | #include
45 |
46 | #if defined(Q_OS_WIN)
47 | # if !defined(QT_QTSERVICE_EXPORT) && !defined(QT_QTSERVICE_IMPORT)
48 | # define QT_QTSERVICE_EXPORT
49 | # elif defined(QT_QTSERVICE_IMPORT)
50 | # if defined(QT_QTSERVICE_EXPORT)
51 | # undef QT_QTSERVICE_EXPORT
52 | # endif
53 | # define QT_QTSERVICE_EXPORT __declspec(dllimport)
54 | # elif defined(QT_QTSERVICE_EXPORT)
55 | # undef QT_QTSERVICE_EXPORT
56 | # define QT_QTSERVICE_EXPORT __declspec(dllexport)
57 | # endif
58 | #else
59 | # define QT_QTSERVICE_EXPORT
60 | #endif
61 |
62 | class QStringList;
63 | class QtServiceControllerPrivate;
64 |
65 | class QT_QTSERVICE_EXPORT QtServiceController
66 | {
67 | Q_DECLARE_PRIVATE(QtServiceController)
68 | public:
69 | enum StartupType
70 | {
71 | AutoStartup = 0, ManualStartup
72 | };
73 |
74 | QtServiceController(const QString &name);
75 | virtual ~QtServiceController();
76 |
77 | bool isInstalled() const;
78 | bool isRunning() const;
79 |
80 | QString serviceName() const;
81 | QString serviceDescription() const;
82 | StartupType startupType() const;
83 | QString serviceFilePath() const;
84 |
85 | static bool install(const QString &serviceFilePath, const QString &account = QString(),
86 | const QString &password = QString());
87 | bool uninstall();
88 |
89 | bool start(const QStringList &arguments);
90 | bool start();
91 | bool stop();
92 | bool pause();
93 | bool resume();
94 | bool sendCommand(int code);
95 |
96 | private:
97 | QtServiceControllerPrivate *d_ptr;
98 | };
99 |
100 | class QtServiceBasePrivate;
101 |
102 | class QT_QTSERVICE_EXPORT QtServiceBase
103 | {
104 | Q_DECLARE_PRIVATE(QtServiceBase)
105 | public:
106 |
107 | enum MessageType
108 | {
109 | Success = 0, Error, Warning, Information
110 | };
111 |
112 | enum ServiceFlag
113 | {
114 | Default = 0x00,
115 | CanBeSuspended = 0x01,
116 | CannotBeStopped = 0x02,
117 | NeedsStopOnShutdown = 0x04
118 | };
119 |
120 | Q_DECLARE_FLAGS(ServiceFlags, ServiceFlag)
121 |
122 | QtServiceBase(int argc, char **argv, const QString &name);
123 | virtual ~QtServiceBase();
124 |
125 | QString serviceName() const;
126 |
127 | QString serviceDescription() const;
128 | void setServiceDescription(const QString &description);
129 |
130 | QtServiceController::StartupType startupType() const;
131 | void setStartupType(QtServiceController::StartupType startupType);
132 |
133 | ServiceFlags serviceFlags() const;
134 | void setServiceFlags(ServiceFlags flags);
135 |
136 | int exec();
137 |
138 | void logMessage(const QString &message, MessageType type = Success,
139 | int id = 0, uint category = 0, const QByteArray &data = QByteArray());
140 |
141 | static QtServiceBase *instance();
142 |
143 | protected:
144 |
145 | virtual void start() = 0;
146 | virtual void stop();
147 | virtual void pause();
148 | virtual void resume();
149 | virtual void processCommand(int code);
150 |
151 | virtual void createApplication(int &argc, char **argv) = 0;
152 |
153 | virtual int executeApplication() = 0;
154 |
155 | private:
156 |
157 | friend class QtServiceSysPrivate;
158 | QtServiceBasePrivate *d_ptr;
159 | };
160 |
161 | template
162 | class QtService : public QtServiceBase
163 | {
164 | public:
165 | QtService(int argc, char **argv, const QString &name)
166 | : QtServiceBase(argc, argv, name), app(0)
167 | { }
168 | ~QtService()
169 | {
170 | }
171 |
172 | protected:
173 | Application *application() const
174 | { return app; }
175 |
176 | virtual void createApplication(int &argc, char **argv)
177 | {
178 | app = new Application(argc, argv);
179 | QCoreApplication *a = app;
180 | Q_UNUSED(a);
181 | }
182 |
183 | virtual int executeApplication()
184 | { return Application::exec(); }
185 |
186 | private:
187 | Application *app;
188 | };
189 |
190 | Q_DECLARE_OPERATORS_FOR_FLAGS(QtServiceBase::ServiceFlags)
191 |
192 | #endif // QTSERVICE_H
193 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/qtservice/qtservice.pri:
--------------------------------------------------------------------------------
1 | INCLUDEPATH += $$PWD
2 | DEPENDPATH += $$PWD
3 | !win32:QT += network
4 | win32:LIBS += -luser32
5 |
6 | qtservice-uselib:!qtservice-buildlib {
7 | LIBS += -L$$QTSERVICE_LIBDIR -l$$QTSERVICE_LIBNAME
8 | } else {
9 | HEADERS += $$PWD/qtservice.h \
10 | $$PWD/qtservice_p.h
11 | SOURCES += $$PWD/qtservice.cpp
12 | win32:SOURCES += $$PWD/qtservice_win.cpp
13 | unix:HEADERS += $$PWD/qtunixsocket.h $$PWD/qtunixserversocket.h
14 | unix:SOURCES += $$PWD/qtservice_unix.cpp $$PWD/qtunixsocket.cpp $$PWD/qtunixserversocket.cpp
15 | }
16 |
17 | win32 {
18 | qtservice-buildlib:shared:DEFINES += QT_QTSERVICE_EXPORT
19 | else:qtservice-uselib:DEFINES += QT_QTSERVICE_IMPORT
20 | }
21 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/qtservice/qtservice_p.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #ifndef QTSERVICE_P_H
42 | #define QTSERVICE_P_H
43 |
44 | #include
45 | #include "qtservice.h"
46 |
47 | class QtServiceControllerPrivate
48 | {
49 | Q_DECLARE_PUBLIC(QtServiceController)
50 | public:
51 | QString serviceName;
52 | QtServiceController *q_ptr;
53 | };
54 |
55 | class QtServiceBasePrivate
56 | {
57 | Q_DECLARE_PUBLIC(QtServiceBase)
58 | public:
59 |
60 | QtServiceBasePrivate(const QString &name);
61 | ~QtServiceBasePrivate();
62 |
63 | QtServiceBase *q_ptr;
64 |
65 | QString serviceDescription;
66 | QtServiceController::StartupType startupType;
67 | QtServiceBase::ServiceFlags serviceFlags;
68 | QStringList args;
69 |
70 | static class QtServiceBase *instance;
71 |
72 | QtServiceController controller;
73 |
74 | void startService();
75 | int run(bool asService, const QStringList &argList);
76 | bool install(const QString &account, const QString &password);
77 |
78 | bool start();
79 |
80 | QString filePath() const;
81 | bool sysInit();
82 | void sysSetPath();
83 | void sysCleanup();
84 | class QtServiceSysPrivate *sysd;
85 | };
86 |
87 | #endif
88 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/qtservice/qtunixserversocket.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #include "qtunixserversocket.h"
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 |
48 | #ifndef SUN_LEN
49 | #define SUN_LEN(ptr) ((size_t)(((struct sockaddr_un *) 0)->sun_path) \
50 | +strlen ((ptr)->sun_path))
51 | #endif
52 |
53 | QtUnixServerSocket::QtUnixServerSocket(const QString &path, QObject *parent)
54 | : QTcpServer(parent)
55 | {
56 | setPath(path);
57 | }
58 |
59 | QtUnixServerSocket::QtUnixServerSocket(QObject *parent)
60 | : QTcpServer(parent)
61 | {
62 | }
63 |
64 | void QtUnixServerSocket::setPath(const QString &path)
65 | {
66 | path_.clear();
67 |
68 | int sock = ::socket(PF_UNIX, SOCK_STREAM, 0);
69 | if (sock != -1) {
70 | struct sockaddr_un addr;
71 | ::memset(&addr, 0, sizeof(struct sockaddr_un));
72 | addr.sun_family = AF_UNIX;
73 | ::unlink(path.toLatin1().constData()); // ### This might need to be changed
74 | unsigned int pathlen = strlen(path.toLatin1().constData());
75 | if (pathlen > sizeof(addr.sun_path)) pathlen = sizeof(addr.sun_path);
76 | ::memcpy(addr.sun_path, path.toLatin1().constData(), pathlen);
77 | if ((::bind(sock, (struct sockaddr *)&addr, SUN_LEN(&addr)) != -1) &&
78 | (::listen(sock, 5) != -1)) {
79 | setSocketDescriptor(sock);
80 | path_ = path;
81 | }
82 | }
83 | }
84 |
85 | void QtUnixServerSocket::close()
86 | {
87 | QTcpServer::close();
88 | if (!path_.isEmpty()) {
89 | ::unlink(path_.toLatin1().constData());
90 | path_.clear();
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/qtservice/qtunixserversocket.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #ifndef QTUNIXSERVERSOCKET_H
42 | #define QTUNIXSERVERSOCKET_H
43 |
44 | #include
45 |
46 | class QtUnixServerSocket : public QTcpServer
47 | {
48 | Q_OBJECT
49 | public:
50 | QtUnixServerSocket(const QString &path, QObject *parent = 0);
51 | QtUnixServerSocket(QObject *parent = 0);
52 |
53 | void setPath(const QString &path);
54 | void close();
55 |
56 | private:
57 | QString path_;
58 | };
59 |
60 |
61 | #endif
62 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/qtservice/qtunixsocket.cpp:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #include "qtunixsocket.h"
42 | #include
43 | #include
44 | #include
45 | #include
46 | #include
47 |
48 | #ifndef SUN_LEN
49 | #define SUN_LEN(ptr) ((size_t)(((struct sockaddr_un *) 0)->sun_path) \
50 | +strlen ((ptr)->sun_path))
51 | #endif
52 |
53 | QtUnixSocket::QtUnixSocket(QObject *parent)
54 | : QTcpSocket(parent)
55 | {
56 | }
57 |
58 | bool QtUnixSocket::connectTo(const QString &path)
59 | {
60 | bool ret = false;
61 | int sock = ::socket(PF_UNIX, SOCK_STREAM, 0);
62 | if (sock != -1) {
63 | struct sockaddr_un addr;
64 | ::memset(&addr, 0, sizeof(struct sockaddr_un));
65 | addr.sun_family = AF_UNIX;
66 | size_t pathlen = strlen(path.toLatin1().constData());
67 | pathlen = qMin(pathlen, sizeof(addr.sun_path));
68 | ::memcpy(addr.sun_path, path.toLatin1().constData(), pathlen);
69 | int err = ::connect(sock, (struct sockaddr *)&addr, SUN_LEN(&addr));
70 | if (err != -1) {
71 | setSocketDescriptor(sock);
72 | ret = true;
73 | } else {
74 | ::close(sock);
75 | }
76 | }
77 | return ret;
78 | }
79 |
--------------------------------------------------------------------------------
/TestWindowsServiceWithLibrarySource/qtservice/qtunixsocket.h:
--------------------------------------------------------------------------------
1 | /****************************************************************************
2 | **
3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
4 | ** Contact: http://www.qt-project.org/legal
5 | **
6 | ** This file is part of the Qt Solutions component.
7 | **
8 | ** $QT_BEGIN_LICENSE:BSD$
9 | ** You may use this file under the terms of the BSD license as follows:
10 | **
11 | ** "Redistribution and use in source and binary forms, with or without
12 | ** modification, are permitted provided that the following conditions are
13 | ** met:
14 | ** * Redistributions of source code must retain the above copyright
15 | ** notice, this list of conditions and the following disclaimer.
16 | ** * Redistributions in binary form must reproduce the above copyright
17 | ** notice, this list of conditions and the following disclaimer in
18 | ** the documentation and/or other materials provided with the
19 | ** distribution.
20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
21 | ** of its contributors may be used to endorse or promote products derived
22 | ** from this software without specific prior written permission.
23 | **
24 | **
25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
36 | **
37 | ** $QT_END_LICENSE$
38 | **
39 | ****************************************************************************/
40 |
41 | #ifndef QTUNIXSOCKET_H
42 | #define QTUNIXSOCKET_H
43 |
44 | #include
45 |
46 | class QtUnixSocket : public QTcpSocket
47 | {
48 | Q_OBJECT
49 | public:
50 | QtUnixSocket(QObject *parent = 0);
51 |
52 | bool connectTo(const QString &path);
53 | };
54 |
55 | #endif
56 |
--------------------------------------------------------------------------------