Commit 9b4ea37f340765ffbe921baa05b740d1bb0885c7

Authored by Thiago Rocha
2 parents 2bff7f03 dcd62bd2
Exists in master

Merge branch 'master' of https://github.com/lightbase/cacic-agente

Conflicts:
	src/ccoleta.h
Showing 47 changed files with 5094 additions and 80 deletions   Show diff stats
cacic-teste/cacic-teste.pro
... ... @@ -21,7 +21,12 @@ SOURCES += \
21 21 testcacic.cpp \
22 22 ../src/ccacic.cpp \
23 23 ../src/cacic_computer.cpp \
24   - ../src/operatingsystem.cpp
  24 + ../src/operatingsystem.cpp \
  25 + ../src/qtservice/src/qtservice.cpp \
  26 + ../src/qtservice/src/qtservice_unix.cpp \
  27 + ../src/qtservice/src/qtservice_win.cpp \
  28 + ../src/qtservice/src/qtunixserversocket.cpp \
  29 + ../src/qtservice/src/qtunixsocket.cpp
25 30  
26 31  
27 32 HEADERS += \
... ... @@ -30,7 +35,11 @@ HEADERS += \
30 35 ../src/cacic_computer.h \
31 36 ../src/cacic_comm.h \
32 37 ../src/console.h \
33   - ../src/operatingsystem.h
  38 + ../src/operatingsystem.h \
  39 + ../src/qtservice/src/qtservice.h \
  40 + ../src/qtservice/src/qtservice_p.h \
  41 + ../src/qtservice/src/qtunixserversocket.h \
  42 + ../src/qtservice/src/qtunixsocket.h
34 43  
35 44 INCLUDEPATH += ../src \
36 45 ../src/crypto++/include/
... ...
cacic-teste/testcacic.cpp
... ... @@ -105,6 +105,7 @@ void CTestCacic::testConsole()
105 105 #if defined(Q_OS_LINUX)
106 106 QVERIFY(console("echo teste").toStdString() == "teste\n");
107 107 #elif defined(Q_OS_WIN)
  108 + qDebug() << console("echo teste");
108 109 QVERIFY(console("echo teste").toStdString() == "teste");
109 110 #else
110 111 QVERIFY(false);
... ... @@ -154,26 +155,6 @@ void CTestCacic::testDeCrypt(){
154 155  
155 156 }
156 157  
157   -void CTestCacic::testInstallCacicStart()
158   -{
159   -// char *argva[] = {"program name", "-host=teste.cacic.cpp", "-user=asda", "-password=qwesd", NULL};
160   -// int argca = sizeof(argva) / sizeof(char*) - 1;
161   -// QCoreApplication a(argca, argva);
162   -
163   -// InstallCacic *oInstallCacic = new InstallCacic(&a);
164   -
165   -// QStringList args;
166   -// for (int i = 0; i<argca; i++)
167   -// args.append(argva[i]);
168   -// // This will cause the application to exit when
169   -// // the task signals finished.
170   -// QObject::connect(oInstallCacic, SIGNAL(finished()), &a, SLOT(quit()));
171   -
172   -// // This will run the task from the application event loop.
173   -// QMetaObject::invokeMethod(oInstallCacic, "run", Qt::QueuedConnection, Q_ARG(QStringList, args), Q_ARG(int, argca));
174   - QVERIFY(false);
175   -}
176   -
177 158 void CTestCacic::testCacicCompToJsonObject()
178 159 {
179 160 // qDebug() << OCacicComp.toJsonObject();
... ... @@ -204,7 +185,7 @@ void CTestCacic::testStartService()
204 185 #ifdef Q_OS_WIN
205 186 exitStatus = OCacic.startProcess("../../install-cacic/debug/install-cacic.exe", true, &ok);
206 187 #else
207   - exitStatus = OCacic.startProcess("../../install-cacic/debug/install-cacic", &ok);
  188 + exitStatus = OCacic.startProcess("../../install-cacic/debug/install-cacic", true, &ok);
208 189 #endif
209 190 QVERIFY(ok);
210 191 }
... ... @@ -238,6 +219,11 @@ void CTestCacic::testSetRegistry()
238 219 QVERIFY(confirmaTeste.value("teste1") == QVariant("Teste 1"));
239 220 }
240 221  
  222 +void CTestCacic::testGetValueFromRegistry()
  223 +{
  224 + QVERIFY(OCacic.getValueFromRegistry("Lightbase", "Teste", "teste1") == QVariant("Teste 1"));
  225 +}
  226 +
241 227 void CTestCacic::testRemoveRegistry()
242 228 {
243 229 OCacic.removeRegistry("Lightbase", "Teste");
... ... @@ -247,6 +233,10 @@ void CTestCacic::testRemoveRegistry()
247 233 confirmaTeste.sync();
248 234 }
249 235  
  236 +void CTestCacic::testIniciarDaemon(){
  237 +
  238 +}
  239 +
250 240 void CTestCacic::cleanupTestCase()
251 241 {
252 242 OCacic.deleteFile("configRequest.json");
... ...
cacic-teste/testcacic.h
... ... @@ -16,6 +16,7 @@
16 16 #include <QJsonObject>
17 17 #include "../install-cacic/installcacic.h"
18 18 #include "../gercols/gercols.h"
  19 +#include "../cacicD/cacicd.h"
19 20  
20 21 class CTestCacic : public QObject
21 22 {
... ... @@ -31,6 +32,7 @@ private:
31 32 QString testIniPath;
32 33 QJsonObject session;
33 34 QString cripTeste;
  35 + cacicD OcacicD;
34 36  
35 37 signals:
36 38  
... ... @@ -55,7 +57,6 @@ private slots:
55 57 void testSslConnection();
56 58 void testEnCrypt();
57 59 void testDeCrypt();
58   - void testInstallCacicStart();
59 60 void testCacicCompToJsonObject();
60 61 void testOperatingSystemToJsonObject();
61 62 void testJsonToFile();
... ... @@ -63,7 +64,9 @@ private slots:
63 64 void testStartService();
64 65 void testReadConfig();
65 66 void testSetRegistry();
  67 + void testGetValueFromRegistry();
66 68 void testRemoveRegistry();
  69 + void testIniciarDaemon();
67 70 void cleanupTestCase();
68 71 };
69 72  
... ...
cacic/cacic.pro
... ... @@ -1,34 +0,0 @@
1   -#-------------------------------------------------
2   -#
3   -# Project created by QtCreator 2014-08-13T13:33:32
4   -#
5   -#-------------------------------------------------
6   -
7   -QT += core
8   -QT -= gui
9   -
10   -TARGET = cacic
11   -CONFIG += console
12   -CONFIG -= app_bundle
13   -
14   -win32 {
15   - LIBS += -LE:\LightBase\cacic-agente-project\cacic-agente\src\crypto++\lib -lcryptopp
16   -} else {
17   - LIBS += -L/usr/lib -lcryptopp
18   -}
19   -
20   -TEMPLATE = app
21   -
22   -SOURCES += \
23   - main.cpp \
24   - ../src/ccacic.cpp \
25   - ../src/cacic_computer.cpp
26   -
27   -
28   -HEADERS += \
29   - ../src/ccacic.h \
30   - ../src/cacic_computer.h \
31   - ../src/cacic_comm.h
32   -
33   -INCLUDEPATH += ../src \
34   - ../src/crypto++/include/
cacic/main.cpp
... ... @@ -1,8 +0,0 @@
1   -#include <QCoreApplication>
2   -
3   -int main(int argc, char *argv[])
4   -{
5   - QCoreApplication a(argc, argv);
6   -
7   - return a.exec();
8   -}
cacicD/cacicD.pro 0 → 100644
... ... @@ -0,0 +1,38 @@
  1 +#-------------------------------------------------
  2 +#
  3 +# Project created by QtCreator 2014-08-18T11:06:08
  4 +#
  5 +#-------------------------------------------------
  6 +
  7 +QT += core
  8 +
  9 +QT -= gui
  10 +
  11 +TARGET = cacicD
  12 +CONFIG += console
  13 +CONFIG -= app_bundle
  14 +win32 {
  15 + LIBS += -LE:\LightBase\cacic-agente-project\cacic-agente\src\crypto++\lib -lcryptopp
  16 +} else {
  17 + LIBS += -L/usr/lib -lcryptopp
  18 +}
  19 +TEMPLATE = app
  20 +
  21 +
  22 +SOURCES += main.cpp \
  23 + ../src/cacic_computer.cpp \
  24 + ../src/ccacic.cpp \
  25 + ../src/ccoleta.cpp \
  26 + ../src/operatingsystem.cpp \
  27 + cacicd.cpp
  28 +
  29 +HEADERS += \
  30 + ../src/cacic_comm.h \
  31 + ../src/cacic_computer.h \
  32 + ../src/ccacic.h \
  33 + ../src/ccoleta.h \
  34 + ../src/console.h \
  35 + ../src/operatingsystem.h \
  36 + cacicd.h
  37 +
  38 +include(../src/qtservice/src/qtservice.pri)
... ...
cacicD/cacicd.cpp 0 → 100644
... ... @@ -0,0 +1,5 @@
  1 +#include "cacicd.h"
  2 +
  3 +cacicD::cacicD()
  4 +{
  5 +}
... ...
cacicD/cacicd.h 0 → 100644
... ... @@ -0,0 +1,10 @@
  1 +#ifndef CACICD_H
  2 +#define CACICD_H
  3 +
  4 +class cacicD
  5 +{
  6 +public:
  7 + cacicD();
  8 +};
  9 +
  10 +#endif // CACICD_H
... ...
cacicD/main.cpp 0 → 100644
... ... @@ -0,0 +1,25 @@
  1 +#include <QCoreApplication>
  2 +#include <QStringList>
  3 +#include <QDir>
  4 +#include <QSettings>
  5 +#include "../src/qtservice/src/qtservice.h"
  6 +
  7 +int main(int argc, char **argv)
  8 +{
  9 +#if !defined(Q_OS_WIN)
  10 + QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, QDir::tempPath());
  11 + qWarning("(Example uses dummy settings file: %s/QtSoftware.conf)", QDir::tempPath().toLatin1().constData());
  12 +#endif
  13 + //int result = processArgs(argc, argv);
  14 + if (QString::fromLocal8Bit(argv[argc-1]) == QLatin1String("-w") ||
  15 + QString::fromLocal8Bit(argv[argc-1]) == QLatin1String("-wait")) {
  16 + printf("\nPress Enter to continue...");
  17 + QFile input;
  18 + input.open(stdin, QIODevice::ReadOnly);
  19 + input.readLine();
  20 + printf("\n");
  21 + }
  22 + //return result;
  23 +}
  24 +
  25 +
... ...
install-cacic/install-cacic.pro.user
1 1 <?xml version="1.0" encoding="UTF-8"?>
2 2 <!DOCTYPE QtCreatorProject>
3   -<!-- Written by QtCreator 3.1.2, 2014-08-15T20:38:37. -->
  3 +<!-- Written by QtCreator 3.1.2, 2014-08-18T11:08:49. -->
4 4 <qtcreator>
5 5 <data>
6 6 <variable>ProjectExplorer.Project.ActiveTarget</variable>
... ... @@ -224,7 +224,7 @@
224 224 <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments">-uninstall</value>
225 225 <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.ProFile">install-cacic.pro</value>
226 226 <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix">false</value>
227   - <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">true</value>
  227 + <value type="bool" key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal">false</value>
228 228 <value type="QString" key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory"></value>
229 229 <value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
230 230 <value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
... ...
install-cacic/installcacic.cpp
... ... @@ -19,24 +19,27 @@ void InstallCacic::run(QStringList argv, int argc) {
19 19 if (ok){
20 20 //conectado, grava a chave na classe;
21 21 oCacic.setChaveCrypt(jsonLogin["reply"].toObject()["chavecrip"].toString());
  22 +#ifdef Q_OS_WIN
22 23 oCacic.setCacicMainFolder("c:/cacic");
  24 +#elif Q_LINUX
  25 + oCacic.setCacicMainFolder("/home/cacic");
  26 +#endif
23 27 oCacic.createFolder(oCacic.getCacicMainFolder());
24 28 //grava chave em registro;
25 29  
26 30 QVariantMap registro;
27 31 registro["key"] = oCacic.getChaveCrypt();
  32 + registro["mainFolder"] = oCacic.getCacicMainFolder();
28 33 oCacic.setValueToRegistry("Lightbase", "Cacic", registro);
29 34 //starta o processo do cacic.
30 35 #ifdef Q_OS_WIN
31   - QString exitStatus = oCacic.startProcess("cacic.exe", true, &ok);
32   - if (!ok)
33   - std::cout << "Erro ao iniciar o processo: "
34   - << exitStatus.toStdString() << "\n";
  36 + QString exitStatus = oCacic.startProcess(oCacic.getCacicMainFolder() + "cacic.exe", true, &ok);
35 37 #else
36 38 oCacic.startProcess("cacic.exe", true, &ok);
37   - if (!ok)
38   - qDebug() << "Erro ao iniciar o processo.";
39 39 #endif
  40 + if (!ok)
  41 + std::cout << "Erro ao iniciar o processo: "
  42 + << exitStatus.toStdString() << "\n";
40 43 } else
41 44 std::cout << "Nao foi possivel realizar o login.\n "
42 45 << jsonLogin["error"].toString().toStdString();
... ...
src/cacic_computer.h
... ... @@ -7,7 +7,7 @@
7 7 #include <QtSerialPort/QSerialPortInfo>
8 8 #include <QtNetwork/QtNetwork>
9 9 #include <QSysInfo>
10   -#include <operatingsystem.h>
  10 +#include "operatingsystem.h"
11 11  
12 12 class CACIC_Computer
13 13 {
... ...
src/ccacic.cpp
... ... @@ -216,6 +216,12 @@ void CCacic::setValueToRegistry(QString organization, QString application, QVari
216 216 registry.sync();
217 217 }
218 218  
  219 +QVariant CCacic::getValueFromRegistry(QString organization, QString application, QString key)
  220 +{
  221 + QSettings registry(organization, application);
  222 + return registry.value(key);
  223 +}
  224 +
219 225 void CCacic::removeRegistry(QString organization, QString application)
220 226 {
221 227 QSettings registry(organization, application);
... ...
src/ccacic.h
... ... @@ -11,9 +11,9 @@
11 11 #include <QJsonDocument>
12 12 #include <QJsonObject>
13 13 #include <QJsonValue>
14   -#include <aes.h>
15   -#include <base64.h>
16   -#include <modes.h>
  14 +#include "../src/crypto++/include/aes.h"
  15 +#include "../src/crypto++/include/base64.h"
  16 +#include "../src/crypto++/include/modes.h"
17 17 //#include <filters.h>
18 18 //#include <hex.h>
19 19 //#include <sha.h>
... ... @@ -37,6 +37,7 @@ public:
37 37 QJsonObject getJsonFromFile(QString filepath);
38 38 QString startProcess(QString pathprogram, bool wait, bool *ok, QStringList arguments = QStringList());
39 39 void setValueToRegistry(QString organization, QString application, QVariantMap values);
  40 + QVariant getValueFromRegistry(QString organization, QString application, QString key);
40 41 void removeRegistry(QString organization, QString application);
41 42  
42 43  
... ...
src/ccoleta.h
... ... @@ -5,6 +5,7 @@
5 5 #include <QJsonObject>
6 6 #include <QDebug>
7 7 #include <cacic_computer.h>
  8 +#include "cacic_computer.h"
8 9  
9 10  
10 11 class CColeta : public QObject
... ...
src/operatingsystem.h
... ... @@ -6,8 +6,8 @@
6 6 #include <QStringList>
7 7 #include <QSysInfo>
8 8  
9   -#include <ccacic.h>
10   -#include <console.h>
  9 +#include "ccacic.h"
  10 +#include "console.h"
11 11  
12 12 class OperatingSystem
13 13 {
... ...
src/qtservice/buildlib/buildlib.pro 0 → 100644
... ... @@ -0,0 +1,13 @@
  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
... ...
src/qtservice/common.pri 0 → 100644
... ... @@ -0,0 +1,10 @@
  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
... ...
src/qtservice/doc/html/classic.css 0 → 100644
... ... @@ -0,0 +1,284 @@
  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 +}
... ...
src/qtservice/doc/html/images/qt-logo.png 0 → 100644

3.98 KB

src/qtservice/doc/html/index.html 0 → 100644
... ... @@ -0,0 +1,50 @@
  1 +<?xml version="1.0" encoding="iso-8859-1"?>
  2 +<!DOCTYPE html
  3 + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 +<!-- index.qdoc -->
  6 +<head>
  7 + <title>Service</title>
  8 + <link href="classic.css" rel="stylesheet" type="text/css" />
  9 +</head>
  10 +<body>
  11 +<table border="0" cellpadding="0" cellspacing="0" width="100%">
  12 +<tr>
  13 +<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="57" height="67" border="0" /></td>
  14 +<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a></td>
  15 +</tr></table><h1 class="title">Service<br /><span class="subtitle"></span>
  16 +</h1>
  17 +<a name="description"></a>
  18 +<h2>Description</h2>
  19 +<p>The <a href="qtservice.html">QtService</a> component is useful for developing Windows services and Unix daemons.</p>
  20 +<p>The project provides a <a href="qtservice.html">QtService</a> template class that can be used to implement service applications, and a <a href="qtservicecontroller.html">QtServiceController</a> class to control a service.</p>
  21 +<p>On Windows systems the implementation uses the Service Control Manager.</p>
  22 +<p>On Unix systems services are implemented as daemons.</p>
  23 +<a name="classes"></a>
  24 +<h2>Classes</h2>
  25 +<ul>
  26 +<li><a href="qtservicecontroller.html">QtServiceController</a></li>
  27 +<li><a href="qtservicebase.html">QtServiceBase</a></li>
  28 +<li><a href="qtservice.html">QtService</a></li>
  29 +</ul>
  30 +<a name="examples"></a>
  31 +<h2>Examples</h2>
  32 +<ul>
  33 +<li><a href="qtservice-example-interactive.html">An Interactive Service</a></li>
  34 +<li><a href="qtservice-example-server.html">A simple HTTP Server</a></li>
  35 +<li><a href="qtservice-example-controller.html">A simple Service Controller</a></li>
  36 +</ul>
  37 +<a name="tested-platforms"></a>
  38 +<h2>Tested platforms</h2>
  39 +<ul>
  40 +<li>Qt 4.4, 4.5 / Windows XP / MSVC.NET 2005</li>
  41 +<li>Qt 4.4, 4.5 / Linux / gcc</li>
  42 +<li>Qt 4.4, 4.5 / MacOS X 10.5 / gcc</li>
  43 +</ul>
  44 +<p /><address><hr /><div align="center">
  45 +<table width="100%" cellspacing="0" border="0"><tr class="address">
  46 +<td width="30%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
  47 +<td width="40%" align="center"><a href="http://qt.nokia.com/doc/trademarks.html">Trademarks</a></td>
  48 +<td width="30%" align="right"><div align="right">Qt Solutions</div></td>
  49 +</tr></table></div></address></body>
  50 +</html>
... ...
src/qtservice/doc/html/qtservice-example-controller.html 0 → 100644
... ... @@ -0,0 +1,186 @@
  1 +<?xml version="1.0" encoding="iso-8859-1"?>
  2 +<!DOCTYPE html
  3 + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 +<!-- controller.qdoc -->
  6 +<head>
  7 + <title>A simple Service Controller</title>
  8 + <link href="classic.css" rel="stylesheet" type="text/css" />
  9 +</head>
  10 +<body>
  11 +<table border="0" cellpadding="0" cellspacing="0" width="100%">
  12 +<tr>
  13 +<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="57" height="67" border="0" /></td>
  14 +<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a></td>
  15 +</tr></table><h1 class="title">A simple Service Controller<br /><span class="subtitle"></span>
  16 +</h1>
  17 +<p>It is a very simple implementation of universal command-line controller. This controller can install and control any service written using <a href="qtservice.html">QtService</a> component. It demonstrates how to use <a href="qtservicecontroller.html">QtServiceController</a> class. On Windows, this is an alternative to using the &quot;Services&quot; Administrative Tool or the built-in <tt>sc.exe</tt> command-line tool to control services.</p>
  18 +<p>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 &quot;Run as Administrator&quot; 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 &quot;Run as Administrator&quot;. 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 &quot;Services&quot; Administrative Tool to manage the service.</p>
  19 +<p>A usability hint: in some circumstances, e.g&#x2e; when running this example on Windows Vista with the &quot;Run as Administrator&quot; 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.</p>
  20 +<p>Here is the complete source code:</p>
  21 +<pre><span class="comment"> /****************************************************************************
  22 + **
  23 + ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
  24 + ** Contact: http://www.qt-project.org/legal
  25 + **
  26 + ** This file is part of the Qt Solutions component.
  27 + **
  28 + ** You may use this file under the terms of the BSD license as follows:
  29 + **
  30 + ** &quot;Redistribution and use in source and binary forms, with or without
  31 + ** modification, are permitted provided that the following conditions are
  32 + ** met:
  33 + ** * Redistributions of source code must retain the above copyright
  34 + ** notice, this list of conditions and the following disclaimer.
  35 + ** * Redistributions in binary form must reproduce the above copyright
  36 + ** notice, this list of conditions and the following disclaimer in
  37 + ** the documentation and/or other materials provided with the
  38 + ** distribution.
  39 + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
  40 + ** the names of its contributors may be used to endorse or promote
  41 + ** products derived from this software without specific prior written
  42 + ** permission.
  43 + **
  44 + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  45 + ** &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  46 + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  47 + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  48 + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  49 + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  50 + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  51 + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  52 + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  53 + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  54 + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.&quot;
  55 + **
  56 + ****************************************************************************/</span>
  57 +
  58 + #include &lt;QtCore/QStringList&gt;
  59 + #include &lt;QtCore/QDir&gt;
  60 + #include &lt;QtCore/QSettings&gt;
  61 + #include &quot;qtservice.h&quot;
  62 +
  63 + int processArgs(int argc, char **argv)
  64 + {
  65 + if (argc &gt; 2) {
  66 + QString arg1(argv[1]);
  67 + if (arg1 == QLatin1String(&quot;-i&quot;) ||
  68 + arg1 == QLatin1String(&quot;-install&quot;)) {
  69 + if (argc &gt; 2) {
  70 + QString account;
  71 + QString password;
  72 + QString path(argv[2]);
  73 + if (argc &gt; 3)
  74 + account = argv[3];
  75 + if (argc &gt; 4)
  76 + password = argv[4];
  77 + printf(&quot;The service %s installed.\n&quot;,
  78 + (QtServiceController::install(path, account, password) ? &quot;was&quot; : &quot;was not&quot;));
  79 + return 0;
  80 + }
  81 + } else {
  82 + QString serviceName(argv[1]);
  83 + QtServiceController controller(serviceName);
  84 + QString option(argv[2]);
  85 + if (option == QLatin1String(&quot;-u&quot;) ||
  86 + option == QLatin1String(&quot;-uninstall&quot;)) {
  87 + printf(&quot;The service \&quot;%s\&quot; %s uninstalled.\n&quot;,
  88 + controller.serviceName().toLatin1().constData(),
  89 + (controller.uninstall() ? &quot;was&quot; : &quot;was not&quot;));
  90 + return 0;
  91 + } else if (option == QLatin1String(&quot;-s&quot;) ||
  92 + option == QLatin1String(&quot;-start&quot;)) {
  93 + QStringList args;
  94 + for (int i = 3; i &lt; argc; ++i)
  95 + args.append(QString::fromLocal8Bit(argv[i]));
  96 + printf(&quot;The service \&quot;%s\&quot; %s started.\n&quot;,
  97 + controller.serviceName().toLatin1().constData(),
  98 + (controller.start(args) ? &quot;was&quot; : &quot;was not&quot;));
  99 + return 0;
  100 + } else if (option == QLatin1String(&quot;-t&quot;) ||
  101 + option == QLatin1String(&quot;-terminate&quot;)) {
  102 + printf(&quot;The service \&quot;%s\&quot; %s stopped.\n&quot;,
  103 + controller.serviceName().toLatin1().constData(),
  104 + (controller.stop() ? &quot;was&quot; : &quot;was not&quot;));
  105 + return 0;
  106 + } else if (option == QLatin1String(&quot;-p&quot;) ||
  107 + option == QLatin1String(&quot;-pause&quot;)) {
  108 + printf(&quot;The service \&quot;%s\&quot; %s paused.\n&quot;,
  109 + controller.serviceName().toLatin1().constData(),
  110 + (controller.pause() ? &quot;was&quot; : &quot;was not&quot;));
  111 + return 0;
  112 + } else if (option == QLatin1String(&quot;-r&quot;) ||
  113 + option == QLatin1String(&quot;-resume&quot;)) {
  114 + printf(&quot;The service \&quot;%s\&quot; %s resumed.\n&quot;,
  115 + controller.serviceName().toLatin1().constData(),
  116 + (controller.resume() ? &quot;was&quot; : &quot;was not&quot;));
  117 + return 0;
  118 + } else if (option == QLatin1String(&quot;-c&quot;) ||
  119 + option == QLatin1String(&quot;-command&quot;)) {
  120 + if (argc &gt; 3) {
  121 + QString codestr(argv[3]);
  122 + int code = codestr.toInt();
  123 + printf(&quot;The command %s sent to the service \&quot;%s\&quot;.\n&quot;,
  124 + (controller.sendCommand(code) ? &quot;was&quot; : &quot;was not&quot;),
  125 + controller.serviceName().toLatin1().constData());
  126 + return 0;
  127 + }
  128 + } else if (option == QLatin1String(&quot;-v&quot;) ||
  129 + option == QLatin1String(&quot;-version&quot;)) {
  130 + bool installed = controller.isInstalled();
  131 + printf(&quot;The service\n&quot;
  132 + &quot;\t\&quot;%s\&quot;\n\n&quot;, controller.serviceName().toLatin1().constData());
  133 + printf(&quot;is %s&quot;, (installed ? &quot;installed&quot; : &quot;not installed&quot;));
  134 + printf(&quot; and %s\n\n&quot;, (controller.isRunning() ? &quot;running&quot; : &quot;not running&quot;));
  135 + if (installed) {
  136 + printf(&quot;path: %s\n&quot;, controller.serviceFilePath().toLatin1().data());
  137 + printf(&quot;description: %s\n&quot;, controller.serviceDescription().toLatin1().data());
  138 + printf(&quot;startup: %s\n&quot;, controller.startupType() == QtServiceController::AutoStartup ? &quot;Auto&quot; : &quot;Manual&quot;);
  139 + }
  140 + return 0;
  141 + }
  142 + }
  143 + }
  144 + printf(&quot;controller [-i PATH | SERVICE_NAME [-v | -u | -s | -t | -p | -r | -c CODE] | -h] [-w]\n\n&quot;
  145 + &quot;\t-i(nstall) PATH\t: Install the service\n&quot;
  146 + &quot;\t-v(ersion)\t: Print status of the service\n&quot;
  147 + &quot;\t-u(ninstall)\t: Uninstall the service\n&quot;
  148 + &quot;\t-s(tart)\t: Start the service\n&quot;
  149 + &quot;\t-t(erminate)\t: Stop the service\n&quot;
  150 + &quot;\t-p(ause)\t: Pause the service\n&quot;
  151 + &quot;\t-r(esume)\t: Resume the service\n&quot;
  152 + &quot;\t-c(ommand) CODE\t: Send a command to the service\n&quot;
  153 + &quot;\t-h(elp)\t\t: Print this help info\n&quot;
  154 + &quot;\t-w(ait)\t\t: Wait for keypress when done\n&quot;);
  155 + return 0;
  156 + }
  157 +
  158 + int main(int argc, char **argv)
  159 + {
  160 + #if !defined(Q_OS_WIN)
  161 + <span class="comment">// QtService stores service settings in SystemScope, which normally require root privileges.</span>
  162 + <span class="comment">// To allow testing this example as non-root, we change the directory of the SystemScope settings file.</span>
  163 + QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, QDir::tempPath());
  164 + qWarning(&quot;(Example uses dummy settings file: %s/QtSoftware.conf)&quot;, QDir::tempPath().toLatin1().constData());
  165 + #endif
  166 +
  167 + int result = processArgs(argc, argv);
  168 +
  169 + if (QString::fromLocal8Bit(argv[argc-1]) == QLatin1String(&quot;-w&quot;) ||
  170 + QString::fromLocal8Bit(argv[argc-1]) == QLatin1String(&quot;-wait&quot;)) {
  171 + printf(&quot;\nPress Enter to continue...&quot;);
  172 + QFile input;
  173 + input.open(stdin, QIODevice::ReadOnly);
  174 + input.readLine();
  175 + printf(&quot;\n&quot;);
  176 + }
  177 +
  178 + return result;
  179 + }</pre>
  180 +<p /><address><hr /><div align="center">
  181 +<table width="100%" cellspacing="0" border="0"><tr class="address">
  182 +<td width="30%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
  183 +<td width="40%" align="center"><a href="http://qt.nokia.com/doc/trademarks.html">Trademarks</a></td>
  184 +<td width="30%" align="right"><div align="right">Qt Solutions</div></td>
  185 +</tr></table></div></address></body>
  186 +</html>
... ...
src/qtservice/doc/html/qtservice-example-interactive.html 0 → 100644
... ... @@ -0,0 +1,152 @@
  1 +<?xml version="1.0" encoding="iso-8859-1"?>
  2 +<!DOCTYPE html
  3 + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 +<!-- interactive.qdoc -->
  6 +<head>
  7 + <title>An Interactive Service</title>
  8 + <link href="classic.css" rel="stylesheet" type="text/css" />
  9 +</head>
  10 +<body>
  11 +<table border="0" cellpadding="0" cellspacing="0" width="100%">
  12 +<tr>
  13 +<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="57" height="67" border="0" /></td>
  14 +<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a></td>
  15 +</tr></table><h1 class="title">An Interactive Service<br /><span class="subtitle"></span>
  16 +</h1>
  17 +<p>This example implements a service with a simple user interface.</p>
  18 +<p>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, <a href="qtservicecontroller.html#sendCommand">QtServiceController::sendCommand</a>() and <a href="qtservicebase.html#processCommand">QtService::processCommand</a>() 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&#x2e; based on Qt's networking classes.</p>
  19 +<p>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.</p>
  20 +<p>This example demonstrates how to subclass the <a href="qtservice.html">QtService</a> class, the use of start(), stop(), pause(), resume(), and how to use processCommand() to receive control commands while running.</p>
  21 +<p>Here is the complete source code:</p>
  22 +<pre><span class="comment"> /****************************************************************************
  23 + **
  24 + ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
  25 + ** Contact: http://www.qt-project.org/legal
  26 + **
  27 + ** This file is part of the Qt Solutions component.
  28 + **
  29 + ** You may use this file under the terms of the BSD license as follows:
  30 + **
  31 + ** &quot;Redistribution and use in source and binary forms, with or without
  32 + ** modification, are permitted provided that the following conditions are
  33 + ** met:
  34 + ** * Redistributions of source code must retain the above copyright
  35 + ** notice, this list of conditions and the following disclaimer.
  36 + ** * Redistributions in binary form must reproduce the above copyright
  37 + ** notice, this list of conditions and the following disclaimer in
  38 + ** the documentation and/or other materials provided with the
  39 + ** distribution.
  40 + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
  41 + ** the names of its contributors may be used to endorse or promote
  42 + ** products derived from this software without specific prior written
  43 + ** permission.
  44 + **
  45 + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  46 + ** &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  47 + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  48 + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  49 + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  50 + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  51 + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  52 + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  53 + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  54 + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  55 + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.&quot;
  56 + **
  57 + ****************************************************************************/</span>
  58 +
  59 + #include &lt;QtGui/QApplication&gt;
  60 + #include &lt;QtGui/QDesktopWidget&gt;
  61 + #include &lt;QtGui/QLabel&gt;
  62 + #include &lt;QtCore/QDir&gt;
  63 + #include &lt;QtCore/QSettings&gt;
  64 + #include &quot;qtservice.h&quot;
  65 +
  66 + class InteractiveService : public QtService&lt;QApplication&gt;
  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&lt;QApplication&gt;(argc, argv, &quot;Qt Interactive Service&quot;), gui(0)
  86 + {
  87 + setServiceDescription(&quot;A Qt service with user interface.&quot;);
  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 &amp; QSysInfo::WV_NT_based) &amp;&amp;
  99 + (QSysInfo::WindowsVersion &gt;= QSysInfo::WV_VISTA)) {
  100 + logMessage( &quot;Service GUI not allowed on Windows Vista. See the documentation for this example for more information.&quot;, QtServiceBase::Error );
  101 + return;
  102 + }
  103 + #endif
  104 +
  105 + qApp-&gt;setQuitOnLastWindowClosed(false);
  106 +
  107 + gui = new QLabel(&quot;Service&quot;, 0, Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint);
  108 + gui-&gt;move(QApplication::desktop()-&gt;availableGeometry().topLeft());
  109 + gui-&gt;show();
  110 + }
  111 +
  112 + void InteractiveService::stop()
  113 + {
  114 + delete gui;
  115 + }
  116 +
  117 + void InteractiveService::pause()
  118 + {
  119 + if (gui)
  120 + gui-&gt;hide();
  121 + }
  122 +
  123 + void InteractiveService::resume()
  124 + {
  125 + if (gui)
  126 + gui-&gt;show();
  127 + }
  128 +
  129 + void InteractiveService::processCommand(int code)
  130 + {
  131 + gui-&gt;setText(&quot;Command code &quot; + QString::number(code));
  132 + gui-&gt;adjustSize();
  133 + }
  134 +
  135 + int main(int argc, char **argv)
  136 + {
  137 + #if !defined(Q_OS_WIN)
  138 + <span class="comment">// QtService stores service settings in SystemScope, which normally require root privileges.</span>
  139 + <span class="comment">// To allow testing this example as non-root, we change the directory of the SystemScope settings file.</span>
  140 + QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, QDir::tempPath());
  141 + qWarning(&quot;(Example uses dummy settings file: %s/QtSoftware.conf)&quot;, QDir::tempPath().toLatin1().constData());
  142 + #endif
  143 + InteractiveService service(argc, argv);
  144 + return service.exec();
  145 + }</pre>
  146 +<p /><address><hr /><div align="center">
  147 +<table width="100%" cellspacing="0" border="0"><tr class="address">
  148 +<td width="30%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
  149 +<td width="40%" align="center"><a href="http://qt.nokia.com/doc/trademarks.html">Trademarks</a></td>
  150 +<td width="30%" align="right"><div align="right">Qt Solutions</div></td>
  151 +</tr></table></div></address></body>
  152 +</html>
... ...
src/qtservice/doc/html/qtservice-example-server.html 0 → 100644
... ... @@ -0,0 +1,159 @@
  1 +<?xml version="1.0" encoding="iso-8859-1"?>
  2 +<!DOCTYPE html
  3 + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 +<!-- server.qdoc -->
  6 +<head>
  7 + <title>A simple HTTP Server</title>
  8 + <link href="classic.css" rel="stylesheet" type="text/css" />
  9 +</head>
  10 +<body>
  11 +<table border="0" cellpadding="0" cellspacing="0" width="100%">
  12 +<tr>
  13 +<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="57" height="67" border="0" /></td>
  14 +<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a></td>
  15 +</tr></table><h1 class="title">A simple HTTP Server<br /><span class="subtitle"></span>
  16 +</h1>
  17 +<p>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.</p>
  18 +<pre><span class="comment"> // HttpDaemon is the the class that implements the simple HTTP server.</span>
  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 + <span class="comment">// When a new client connects, the server constructs a QTcpSocket and all</span>
  35 + <span class="comment">// communication with the client is done over this QTcpSocket. QTcpSocket</span>
  36 + <span class="comment">// works asynchronously, this means that all the communication is done</span>
  37 + <span class="comment">// in the two slots readClient() and discardClient().</span>
  38 + QTcpSocket* s = new QTcpSocket(this);
  39 + connect(s, SIGNAL(readyRead()), this, SLOT(readClient()));
  40 + connect(s, SIGNAL(disconnected()), this, SLOT(discardClient()));
  41 + s-&gt;setSocketDescriptor(socket);
  42 +
  43 + QtServiceBase::instance()-&gt;logMessage(&quot;New Connection&quot;);
  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 + <span class="comment">// This slot is called when the client sent data to the server. The</span>
  63 + <span class="comment">// server looks if it was a get request and sends a very simple HTML</span>
  64 + <span class="comment">// document back.</span>
  65 + QTcpSocket* socket = (QTcpSocket*)sender();
  66 + if (socket-&gt;canReadLine()) {
  67 + QStringList tokens = QString(socket-&gt;readLine()).split(QRegExp(&quot;[ \r\n][ \r\n]*&quot;));
  68 + if (tokens[0] == &quot;GET&quot;) {
  69 + QTextStream os(socket);
  70 + os.setAutoDetectUnicode(true);
  71 + os &lt;&lt; &quot;HTTP/1.0 200 Ok\r\n&quot;
  72 + &quot;Content-Type: text/html; charset=\&quot;utf-8\&quot;\r\n&quot;
  73 + &quot;\r\n&quot;
  74 + &quot;&lt;h1&gt;Nothing to see here&lt;/h1&gt;\n&quot;
  75 + &lt;&lt; QDateTime::currentDateTime().toString() &lt;&lt; &quot;\n&quot;;
  76 + socket-&gt;close();
  77 +
  78 + QtServiceBase::instance()-&gt;logMessage(&quot;Wrote to client&quot;);
  79 +
  80 + if (socket-&gt;state() == QTcpSocket::UnconnectedState) {
  81 + delete socket;
  82 + QtServiceBase::instance()-&gt;logMessage(&quot;Connection closed&quot;);
  83 + }
  84 + }
  85 + }
  86 + }
  87 + void discardClient()
  88 + {
  89 + QTcpSocket* socket = (QTcpSocket*)sender();
  90 + socket-&gt;deleteLater();
  91 +
  92 + QtServiceBase::instance()-&gt;logMessage(&quot;Connection closed&quot;);
  93 + }
  94 +
  95 + private:
  96 + bool disabled;
  97 + };</pre>
  98 +<p>The server implementation uses the <a href="qtservicebase.html#logMessage">QtService::logMessage</a>() 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.</p>
  99 +<p>The <tt>HttpService</tt> class subclasses <a href="qtservice.html">QtService</a> to implement the service functionality.</p>
  100 +<pre> class HttpService : public QtService&lt;QCoreApplication&gt;
  101 + {
  102 + public:
  103 + HttpService(int argc, char **argv)
  104 + : QtService&lt;QCoreApplication&gt;(argc, argv, &quot;Qt HTTP Daemon&quot;)
  105 + {
  106 + setServiceDescription(&quot;A dummy HTTP service implemented with Qt&quot;);
  107 + setServiceFlags(QtServiceBase::CanBeSuspended);
  108 + }</pre>
  109 +<p>The constructor calls the <a href="qtservice.html">QtService</a> constructor instantiated with <a href="http://qt.nokia.com/doc/4.6/qcoreapplication.html">QCoreApplication</a> since our service will not use GUI. The first two parameters of our constructor are passed to <a href="qtservice.html">QtService</a>. The last parameter, &quot;Qt HTTP Daemon&quot;, is the name of the service.</p>
  110 +<pre> protected:
  111 + void start()
  112 + {
  113 + QCoreApplication *app = application();
  114 +
  115 + quint16 port = (app-&gt;argc() &gt; 1) ?
  116 + QString::fromLocal8Bit(app-&gt;argv()[1]).toUShort() : 8080;
  117 + daemon = new HttpDaemon(port, app);
  118 +
  119 + if (!daemon-&gt;isListening()) {
  120 + logMessage(QString(&quot;Failed to bind to port %1&quot;).arg(daemon-&gt;serverPort()), QtServiceBase::Error);
  121 + app-&gt;quit();
  122 + }
  123 + }</pre>
  124 +<p>The implementation of <tt>start()</tt> 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.</p>
  125 +<pre> void pause()
  126 + {
  127 + daemon-&gt;pause();
  128 + }
  129 +
  130 + void resume()
  131 + {
  132 + daemon-&gt;resume();
  133 + }
  134 +
  135 + private:
  136 + HttpDaemon *daemon;
  137 + };</pre>
  138 +<p>The implementations of pause() and resume() forward the request to the server object.</p>
  139 +<pre> #include &quot;main.moc&quot;
  140 +
  141 + int main(int argc, char **argv)
  142 + {
  143 + #if !defined(Q_OS_WIN)
  144 + <span class="comment">// QtService stores service settings in SystemScope, which normally require root privileges.</span>
  145 + <span class="comment">// To allow testing this example as non-root, we change the directory of the SystemScope settings file.</span>
  146 + QSettings::setPath(QSettings::NativeFormat, QSettings::SystemScope, QDir::tempPath());
  147 + qWarning(&quot;(Example uses dummy settings file: %s/QtSoftware.conf)&quot;, QDir::tempPath().toLatin1().constData());
  148 + #endif
  149 + HttpService service(argc, argv);
  150 + return service.exec();
  151 + }</pre>
  152 +<p>The main entry point function creates the service object and uses the <tt>exec()</tt> function to execute the service.</p>
  153 +<p /><address><hr /><div align="center">
  154 +<table width="100%" cellspacing="0" border="0"><tr class="address">
  155 +<td width="30%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
  156 +<td width="40%" align="center"><a href="http://qt.nokia.com/doc/trademarks.html">Trademarks</a></td>
  157 +<td width="30%" align="right"><div align="right">Qt Solutions</div></td>
  158 +</tr></table></div></address></body>
  159 +</html>
... ...
src/qtservice/doc/html/qtservice-members.html 0 → 100644
... ... @@ -0,0 +1,52 @@
  1 +<?xml version="1.0" encoding="iso-8859-1"?>
  2 +<!DOCTYPE html
  3 + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 +<!-- qtservice.cpp -->
  6 +<head>
  7 + <title>List of All Members for QtService</title>
  8 + <link href="classic.css" rel="stylesheet" type="text/css" />
  9 +</head>
  10 +<body>
  11 +<table border="0" cellpadding="0" cellspacing="0" width="100%">
  12 +<tr>
  13 +<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="57" height="67" border="0" /></td>
  14 +<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a></td>
  15 +</tr></table><h1 class="title">List of All Members for QtService</h1>
  16 +<p>This is the complete list of members for <a href="qtservice.html">QtService</a>, including inherited members.</p>
  17 +<p><table class="propsummary" width="100%" border="0" cellpadding="0" cellspacing="0">
  18 +<tr><td width="45%" valign="top"><ul>
  19 +<li><div class="fn">enum <b><a href="qtservicebase.html#MessageType-enum">MessageType</a></b></div></li>
  20 +<li><div class="fn">enum <b><a href="qtservicebase.html#ServiceFlag-enum">ServiceFlag</a></b></div></li>
  21 +<li><div class="fn">flags <b><a href="qtservicebase.html#ServiceFlag-enum">ServiceFlags</a></b></div></li>
  22 +<li><div class="fn"><b><a href="qtservice.html#QtService">QtService</a></b> ( int, char **, const QString &amp; )</div></li>
  23 +<li><div class="fn"><b><a href="qtservice.html#dtor.QtService">~QtService</a></b> ()</div></li>
  24 +<li><div class="fn"><b><a href="qtservice.html#application">application</a></b> () const : Application *</div></li>
  25 +<li><div class="fn"><b><a href="qtservice.html#createApplication">createApplication</a></b> ( int &amp;, char ** )</div></li>
  26 +<li><div class="fn"><b><a href="qtservicebase.html#exec">exec</a></b> () : int</div></li>
  27 +<li><div class="fn"><b><a href="qtservice.html#executeApplication">executeApplication</a></b> () : int</div></li>
  28 +<li><div class="fn"><b><a href="qtservicebase.html#instance">instance</a></b> () : QtServiceBase *</div></li>
  29 +<li><div class="fn"><b><a href="qtservicebase.html#logMessage">logMessage</a></b> ( const QString &amp;, MessageType, int, uint, const QByteArray &amp; )</div></li>
  30 +<li><div class="fn"><b><a href="qtservicebase.html#pause">pause</a></b> ()</div></li>
  31 +</ul></td><td valign="top"><ul>
  32 +<li><div class="fn"><b><a href="qtservicebase.html#processCommand">processCommand</a></b> ( int )</div></li>
  33 +<li><div class="fn"><b><a href="qtservicebase.html#resume">resume</a></b> ()</div></li>
  34 +<li><div class="fn"><b><a href="qtservicebase.html#serviceDescription">serviceDescription</a></b> () const : QString</div></li>
  35 +<li><div class="fn"><b><a href="qtservicebase.html#serviceFlags">serviceFlags</a></b> () const : ServiceFlags</div></li>
  36 +<li><div class="fn"><b><a href="qtservicebase.html#serviceName">serviceName</a></b> () const : QString</div></li>
  37 +<li><div class="fn"><b><a href="qtservicebase.html#setServiceDescription">setServiceDescription</a></b> ( const QString &amp; )</div></li>
  38 +<li><div class="fn"><b><a href="qtservicebase.html#setServiceFlags">setServiceFlags</a></b> ( ServiceFlags )</div></li>
  39 +<li><div class="fn"><b><a href="qtservicebase.html#setStartupType">setStartupType</a></b> ( QtServiceController::StartupType )</div></li>
  40 +<li><div class="fn"><b><a href="qtservicebase.html#start">start</a></b> ()</div></li>
  41 +<li><div class="fn"><b><a href="qtservicebase.html#startupType">startupType</a></b> () const : QtServiceController::StartupType</div></li>
  42 +<li><div class="fn"><b><a href="qtservicebase.html#stop">stop</a></b> ()</div></li>
  43 +</ul>
  44 +</td></tr>
  45 +</table></p>
  46 +<p /><address><hr /><div align="center">
  47 +<table width="100%" cellspacing="0" border="0"><tr class="address">
  48 +<td width="30%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
  49 +<td width="40%" align="center"><a href="http://qt.nokia.com/doc/trademarks.html">Trademarks</a></td>
  50 +<td width="30%" align="right"><div align="right">Qt Solutions</div></td>
  51 +</tr></table></div></address></body>
  52 +</html>
... ...
src/qtservice/doc/html/qtservice.dcf 0 → 100644
... ... @@ -0,0 +1,79 @@
  1 +<!DOCTYPE DCF>
  2 +<DCF ref="index.html" icon="qtservice.png" imagedir="../../gif" title="Qt Solutions: Service Documentation">
  3 +<section ref="classes.html" title="Classes">
  4 + <section ref="qtservice.html" title="QtService Class Reference">
  5 + <keyword ref="qtservice.html">QtService</keyword>
  6 + <keyword ref="qtservice.html#application">application</keyword>
  7 + <keyword ref="qtservice.html#createApplication">createApplication</keyword>
  8 + <keyword ref="qtservice.html#executeApplication">executeApplication</keyword>
  9 + <section ref="qtservice-members.html" title="List of all members"/>
  10 + </section>
  11 + <section ref="qtservicebase.html" title="QtServiceBase Class Reference">
  12 + <keyword ref="qtservicebase.html">QtServiceBase</keyword>
  13 + <keyword ref="qtservicebase.html#MessageType-enum">MessageType</keyword>
  14 + <keyword ref="qtservicebase.html#MessageType-enum">QtServiceBase::Warning</keyword>
  15 + <keyword ref="qtservicebase.html#MessageType-enum">QtServiceBase::Error</keyword>
  16 + <keyword ref="qtservicebase.html#MessageType-enum">QtServiceBase::Success</keyword>
  17 + <keyword ref="qtservicebase.html#MessageType-enum">QtServiceBase::Information</keyword>
  18 + <keyword ref="qtservicebase.html#ServiceFlag-enum">ServiceFlag</keyword>
  19 + <keyword ref="qtservicebase.html#ServiceFlag-enum">ServiceFlags</keyword>
  20 + <keyword ref="qtservicebase.html#ServiceFlag-enum">QtServiceBase::Default</keyword>
  21 + <keyword ref="qtservicebase.html#ServiceFlag-enum">QtServiceBase::NeedsStopOnShutdown</keyword>
  22 + <keyword ref="qtservicebase.html#ServiceFlag-enum">QtServiceBase::CannotBeStopped</keyword>
  23 + <keyword ref="qtservicebase.html#ServiceFlag-enum">QtServiceBase::CanBeSuspended</keyword>
  24 + <keyword ref="qtservicebase.html#createApplication">createApplication</keyword>
  25 + <keyword ref="qtservicebase.html#exec">exec</keyword>
  26 + <keyword ref="qtservicebase.html#executeApplication">executeApplication</keyword>
  27 + <keyword ref="qtservicebase.html#instance">instance</keyword>
  28 + <keyword ref="qtservicebase.html#logMessage">logMessage</keyword>
  29 + <keyword ref="qtservicebase.html#pause">pause</keyword>
  30 + <keyword ref="qtservicebase.html#processCommand">processCommand</keyword>
  31 + <keyword ref="qtservicebase.html#resume">resume</keyword>
  32 + <keyword ref="qtservicebase.html#serviceDescription">serviceDescription</keyword>
  33 + <keyword ref="qtservicebase.html#serviceFlags">serviceFlags</keyword>
  34 + <keyword ref="qtservicebase.html#serviceName">serviceName</keyword>
  35 + <keyword ref="qtservicebase.html#setServiceDescription">setServiceDescription</keyword>
  36 + <keyword ref="qtservicebase.html#setServiceFlags">setServiceFlags</keyword>
  37 + <keyword ref="qtservicebase.html#setStartupType">setStartupType</keyword>
  38 + <keyword ref="qtservicebase.html#start">start</keyword>
  39 + <keyword ref="qtservicebase.html#startupType">startupType</keyword>
  40 + <keyword ref="qtservicebase.html#stop">stop</keyword>
  41 + <section ref="qtservicebase-members.html" title="List of all members"/>
  42 + </section>
  43 + <section ref="qtservicecontroller.html" title="QtServiceController Class Reference">
  44 + <keyword ref="qtservicecontroller.html">QtServiceController</keyword>
  45 + <keyword ref="qtservicecontroller.html#StartupType-enum">StartupType</keyword>
  46 + <keyword ref="qtservicecontroller.html#StartupType-enum">QtServiceController::AutoStartup</keyword>
  47 + <keyword ref="qtservicecontroller.html#StartupType-enum">QtServiceController::ManualStartup</keyword>
  48 + <keyword ref="qtservicecontroller.html#install">install</keyword>
  49 + <keyword ref="qtservicecontroller.html#isInstalled">isInstalled</keyword>
  50 + <keyword ref="qtservicecontroller.html#isRunning">isRunning</keyword>
  51 + <keyword ref="qtservicecontroller.html#pause">pause</keyword>
  52 + <keyword ref="qtservicecontroller.html#resume">resume</keyword>
  53 + <keyword ref="qtservicecontroller.html#sendCommand">sendCommand</keyword>
  54 + <keyword ref="qtservicecontroller.html#serviceDescription">serviceDescription</keyword>
  55 + <keyword ref="qtservicecontroller.html#serviceFilePath">serviceFilePath</keyword>
  56 + <keyword ref="qtservicecontroller.html#serviceName">serviceName</keyword>
  57 + <keyword ref="qtservicecontroller.html#start">start</keyword>
  58 + <keyword ref="qtservicecontroller.html#startupType">startupType</keyword>
  59 + <keyword ref="qtservicecontroller.html#stop">stop</keyword>
  60 + <keyword ref="qtservicecontroller.html#uninstall">uninstall</keyword>
  61 + <section ref="qtservicecontroller-members.html" title="List of all members"/>
  62 + </section>
  63 +</section>
  64 +<section ref="overviews.html" title="Overviews">
  65 + <section ref="qtservice-example-server.html" title="A simple HTTP Server">
  66 + <keyword ref="qtservice-example-server.html">A simple HTTP Server</keyword>
  67 + </section>
  68 + <section ref="qtservice-example-controller.html" title="A simple Service Controller">
  69 + <keyword ref="qtservice-example-controller.html">A simple Service Controller</keyword>
  70 + </section>
  71 + <section ref="qtservice-example-interactive.html" title="An Interactive Service">
  72 + <keyword ref="qtservice-example-interactive.html">An Interactive Service</keyword>
  73 + </section>
  74 + <section ref="index.html" title="Service">
  75 + <keyword ref="index.html">Service</keyword>
  76 + </section>
  77 +</section>
  78 +<section ref="examples.html" title="Tutorial &amp; Examples"/>
  79 +</DCF>
... ...
src/qtservice/doc/html/qtservice.html 0 → 100644
... ... @@ -0,0 +1,106 @@
  1 +<?xml version="1.0" encoding="iso-8859-1"?>
  2 +<!DOCTYPE html
  3 + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 +<!-- qtservice.cpp -->
  6 +<head>
  7 + <title>QtService Class Reference</title>
  8 + <link href="classic.css" rel="stylesheet" type="text/css" />
  9 +</head>
  10 +<body>
  11 +<table border="0" cellpadding="0" cellspacing="0" width="100%">
  12 +<tr>
  13 +<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="57" height="67" border="0" /></td>
  14 +<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a></td>
  15 +</tr></table><h1 class="title">QtService Class Reference</h1>
  16 +<p>The QtService is a convenient template class that allows you to create a service for a particular application type. <a href="#details">More...</a></p>
  17 +<pre> #include &lt;QtService&gt;</pre><p>Inherits <a href="qtservicebase.html">QtServiceBase</a>.</p>
  18 +<ul>
  19 +<li><a href="qtservice-members.html">List of all members, including inherited members</a></li>
  20 +</ul>
  21 +<hr />
  22 +<a name="public-functions"></a>
  23 +<h2>Public Functions</h2>
  24 +<table class="alignedsummary" border="0" cellpadding="0" cellspacing="0" width="100%">
  25 +<tr><td class="memItemLeft" align="right" valign="top"></td><td class="memItemRight" valign="bottom"><b><a href="qtservice.html#QtService">QtService</a></b> ( int <i>argc</i>, char ** <i>argv</i>, const QString &amp; <i>name</i> )</td></tr>
  26 +<tr><td class="memItemLeft" align="right" valign="top"></td><td class="memItemRight" valign="bottom"><b><a href="qtservice.html#dtor.QtService">~QtService</a></b> ()</td></tr>
  27 +</table>
  28 +<ul>
  29 +<li><div bar="2" class="fn"></div>9 public functions inherited from <a href="qtservicebase.html#public-functions">QtServiceBase</a></li>
  30 +</ul>
  31 +<hr />
  32 +<a name="protected-functions"></a>
  33 +<h2>Protected Functions</h2>
  34 +<table class="alignedsummary" border="0" cellpadding="0" cellspacing="0" width="100%">
  35 +<tr><td class="memItemLeft" align="right" valign="top">Application * </td><td class="memItemRight" valign="bottom"><b><a href="qtservice.html#application">application</a></b> () const</td></tr>
  36 +</table>
  37 +<hr />
  38 +<a name="reimplemented-protected-functions"></a>
  39 +<h2>Reimplemented Protected Functions</h2>
  40 +<table class="alignedsummary" border="0" cellpadding="0" cellspacing="0" width="100%">
  41 +<tr><td class="memItemLeft" align="right" valign="top">virtual void </td><td class="memItemRight" valign="bottom"><b><a href="qtservice.html#createApplication">createApplication</a></b> ( int &amp; <i>argc</i>, char ** <i>argv</i> )</td></tr>
  42 +<tr><td class="memItemLeft" align="right" valign="top">virtual int </td><td class="memItemRight" valign="bottom"><b><a href="qtservice.html#executeApplication">executeApplication</a></b> ()</td></tr>
  43 +</table>
  44 +<ul>
  45 +<li><div bar="2" class="fn"></div>7 protected functions inherited from <a href="qtservicebase.html#protected-functions">QtServiceBase</a></li>
  46 +</ul>
  47 +<h3>Additional Inherited Members</h3>
  48 +<ul>
  49 +<li><div class="fn"></div>1 static public member inherited from <a href="qtservicebase.html#static-public-members">QtServiceBase</a></li>
  50 +</ul>
  51 +<a name="details"></a>
  52 +<hr />
  53 +<h2>Detailed Description</h2>
  54 +<p>The QtService is a convenient template class that allows you to create a service for a particular application type.</p>
  55 +<p>A Windows service or Unix daemon (a &quot;service&quot;), is a program that runs &quot;in the background&quot; 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.</p>
  56 +<p>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, <a href="qtservicecontroller.html#sendCommand">QtServiceController::sendCommand</a>() and <a href="qtservicebase.html#processCommand">QtService::processCommand</a>() 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&#x2e; based on Qt's networking classes. (In certain circumstances, a service may provide a GUI itself, ref. the &quot;interactive&quot; example documentation).</p>
  57 +<p><b>Note:</b> On Unix systems, this class relies on facilities provided by the <a href="http://qt.nokia.com/doc/4.6/qtnetwork.html">QtNetwork</a> module, provided as part of the Qt Open Source Edition and certain <a href="http://qt.nokia.com/doc/4.6/commercialeditions.html">Qt Commercial Editions</a>.</p>
  58 +<p>The QtService class functionality is inherited from <a href="qtservicebase.html">QtServiceBase</a>, but in addition the QtService class binds an instance of <a href="qtservicebase.html">QtServiceBase</a> with an application type.</p>
  59 +<p>Typically, you will create a service by subclassing the QtService template class. For example:</p>
  60 +<pre> class MyService : public QtService&lt;QApplication&gt;
  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 + };</pre>
  73 +<p>The application type can be <a href="http://qt.nokia.com/doc/4.6/qcoreapplication.html">QCoreApplication</a> for services without GUI, <a href="http://qt.nokia.com/doc/4.6/qapplication.html">QApplication</a> for services with GUI or you can use your own custom application type.</p>
  74 +<p>You must reimplement the <a href="qtservicebase.html#start">QtServiceBase::start</a>() function to perform the service's work. Usually you create some main object on the heap which is the heart of your service.</p>
  75 +<p>In addition, you might want to reimplement the <a href="qtservicebase.html#pause">QtServiceBase::pause</a>(), <a href="qtservicebase.html#processCommand">QtServiceBase::processCommand</a>(), <a href="qtservicebase.html#resume">QtServiceBase::resume</a>() and <a href="qtservicebase.html#stop">QtServiceBase::stop</a>() to intervene the service's process on controller requests. You can control any given service using an instance of the <a href="qtservicecontroller.html">QtServiceController</a> 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.</p>
  76 +<p>Your custom service is typically instantiated in the application's main function. Then the main function will call your service's <a href="qtservicebase.html#exec">exec</a>() function, and return the result of that call. For example:</p>
  77 +<pre> int main(int argc, char **argv)
  78 + {
  79 + MyService service(argc, argv);
  80 + return service.exec();
  81 + }</pre>
  82 +<p>When the <a href="qtservicebase.html#exec">exec</a>() function is called, it will parse the <a href="qtservicebase.html#servicespecificarguments">service specific arguments</a> passed in <tt>argv</tt>, perform the required actions, and exit.</p>
  83 +<p>If none of the arguments is recognized as service specific, <a href="qtservicebase.html#exec">exec</a>() will first call the <a href="qtservice.html#createApplication">createApplication</a>() function, then <a href="qtservice.html#executeApplication">executeApplication</a>() and finally the <a href="qtservicebase.html#start">start</a>() function. In the end, <a href="qtservicebase.html#exec">exec</a>() returns while the service continues in its own process waiting for commands from the service controller.</p>
  84 +<p>See also <a href="qtservicebase.html">QtServiceBase</a> and <a href="qtservicecontroller.html">QtServiceController</a>.</p>
  85 +<hr />
  86 +<h2>Member Function Documentation</h2>
  87 +<h3 class="fn"><a name="QtService"></a>QtService::QtService ( int <i>argc</i>, char ** <i>argv</i>, const <a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> &amp; <i>name</i> )</h3>
  88 +<p>Constructs a <a href="qtservice.html">QtService</a> object called <i>name</i>. The <i>argc</i> and <i>argv</i> parameters are parsed after the <a href="qtservicebase.html#exec">exec</a>() function has been called. Then they are passed to the application's constructor.</p>
  89 +<p>There can only be one <a href="qtservice.html">QtService</a> object in a process.</p>
  90 +<p>See also <a href="qtservicebase.html#QtServiceBase">QtServiceBase</a>().</p>
  91 +<h3 class="fn"><a name="dtor.QtService"></a>QtService::~QtService ()</h3>
  92 +<p>Destroys the service object.</p>
  93 +<h3 class="fn"><a name="application"></a>Application * QtService::application () const&nbsp;&nbsp;<tt> [protected]</tt></h3>
  94 +<p>Returns a pointer to the application object.</p>
  95 +<h3 class="fn"><a name="createApplication"></a>void QtService::createApplication ( int &amp; <i>argc</i>, char ** <i>argv</i> )&nbsp;&nbsp;<tt> [virtual protected]</tt></h3>
  96 +<p>Reimplemented from <a href="qtservicebase.html#createApplication">QtServiceBase::createApplication</a>().</p>
  97 +<p>Creates application object of type Application passing <i>argc</i> and <i>argv</i> to its constructor.</p>
  98 +<h3 class="fn"><a name="executeApplication"></a>int QtService::executeApplication ()&nbsp;&nbsp;<tt> [virtual protected]</tt></h3>
  99 +<p>Reimplemented from <a href="qtservicebase.html#executeApplication">QtServiceBase::executeApplication</a>().</p>
  100 +<p /><address><hr /><div align="center">
  101 +<table width="100%" cellspacing="0" border="0"><tr class="address">
  102 +<td width="30%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
  103 +<td width="40%" align="center"><a href="http://qt.nokia.com/doc/trademarks.html">Trademarks</a></td>
  104 +<td width="30%" align="right"><div align="right">Qt Solutions</div></td>
  105 +</tr></table></div></address></body>
  106 +</html>
... ...
src/qtservice/doc/html/qtservice.index 0 → 100644
... ... @@ -0,0 +1,117 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE QDOCINDEX>
  3 +<INDEX url="" title="Qt Solutions: Service Documentation" version="">
  4 + <namespace access="public" threadsafety="unspecified" status="commendable" name="" href="" location="" module="">
  5 + <class access="public" threadsafety="unspecified" status="commendable" name="QtServiceController" href="qtservicecontroller.html" location="qtservice.h" bases="" module="">
  6 + <enum access="public" threadsafety="unspecified" status="commendable" name="StartupType" fullname="QtServiceController::StartupType" href="qtservicecontroller.html#StartupType-enum" location="qtservice.h">
  7 + <value name="AutoStartup" value="0"/>
  8 + <value name="ManualStartup" value="1"/>
  9 + </enum>
  10 + <function access="public" threadsafety="unspecified" status="commendable" name="QtServiceController" fullname="QtServiceController::QtServiceController" href="qtservicecontroller.html#QtServiceController" location="qtservice.h" virtual="non" meta="constructor" const="false" static="false" overload="false" type="" signature="QtServiceController(const QString &amp; name)">
  11 + <parameter left="const QString &amp;" right="" name="name" default=""/>
  12 + </function>
  13 + <function access="public" threadsafety="unspecified" status="commendable" name="~QtServiceController" fullname="QtServiceController::~QtServiceController" href="qtservicecontroller.html#dtor.QtServiceController" location="qtservice.h" virtual="impure" meta="destructor" const="false" static="false" overload="false" type="" signature="~QtServiceController()"/>
  14 + <function access="public" threadsafety="unspecified" status="commendable" name="isInstalled" fullname="QtServiceController::isInstalled" href="qtservicecontroller.html#isInstalled" location="qtservice_win.cpp" virtual="non" meta="plain" const="true" static="false" overload="false" type="bool" signature="isInstalled() const"/>
  15 + <function access="public" threadsafety="unspecified" status="commendable" name="isRunning" fullname="QtServiceController::isRunning" href="qtservicecontroller.html#isRunning" location="qtservice_win.cpp" virtual="non" meta="plain" const="true" static="false" overload="false" type="bool" signature="isRunning() const"/>
  16 + <function access="public" threadsafety="unspecified" status="commendable" name="serviceName" fullname="QtServiceController::serviceName" href="qtservicecontroller.html#serviceName" location="qtservice.h" virtual="non" meta="plain" const="true" static="false" overload="false" type="QString" signature="serviceName() const"/>
  17 + <function access="public" threadsafety="unspecified" status="commendable" name="serviceDescription" fullname="QtServiceController::serviceDescription" href="qtservicecontroller.html#serviceDescription" location="qtservice_win.cpp" virtual="non" meta="plain" const="true" static="false" overload="false" type="QString" signature="serviceDescription() const"/>
  18 + <function access="public" threadsafety="unspecified" status="commendable" name="startupType" fullname="QtServiceController::startupType" href="qtservicecontroller.html#startupType" location="qtservice_win.cpp" virtual="non" meta="plain" const="true" static="false" overload="false" type="StartupType" signature="startupType() const"/>
  19 + <function access="public" threadsafety="unspecified" status="commendable" name="serviceFilePath" fullname="QtServiceController::serviceFilePath" href="qtservicecontroller.html#serviceFilePath" location="qtservice_win.cpp" virtual="non" meta="plain" const="true" static="false" overload="false" type="QString" signature="serviceFilePath() const"/>
  20 + <function access="public" threadsafety="unspecified" status="commendable" name="install" fullname="QtServiceController::install" href="qtservicecontroller.html#install" location="qtservice.h" virtual="non" meta="plain" const="false" static="true" overload="false" type="bool" signature="install(const QString &amp; serviceFilePath, const QString &amp; account, const QString &amp; password)">
  21 + <parameter left="const QString &amp;" right="" name="serviceFilePath" default=""/>
  22 + <parameter left="const QString &amp;" right="" name="account" default="QString()"/>
  23 + <parameter left="const QString &amp;" right="" name="password" default="QString()"/>
  24 + </function>
  25 + <function access="public" threadsafety="unspecified" status="commendable" name="uninstall" fullname="QtServiceController::uninstall" href="qtservicecontroller.html#uninstall" location="qtservice_win.cpp" virtual="non" meta="plain" const="false" static="false" overload="false" type="bool" signature="uninstall()"/>
  26 + <function access="public" threadsafety="unspecified" status="commendable" name="start" fullname="QtServiceController::start" href="qtservicecontroller.html#start" location="qtservice_win.cpp" virtual="non" meta="plain" const="false" static="false" overload="false" type="bool" signature="start(const QStringList &amp; arguments)">
  27 + <parameter left="const QStringList &amp;" right="" name="arguments" default=""/>
  28 + </function>
  29 + <function access="public" threadsafety="unspecified" status="commendable" name="start" fullname="QtServiceController::start" href="qtservicecontroller.html#start-2" location="qtservice.h" virtual="non" meta="plain" const="false" static="false" overload="true" overload-number="2" type="bool" signature="start()"/>
  30 + <function access="public" threadsafety="unspecified" status="commendable" name="stop" fullname="QtServiceController::stop" href="qtservicecontroller.html#stop" location="qtservice_win.cpp" virtual="non" meta="plain" const="false" static="false" overload="false" type="bool" signature="stop()"/>
  31 + <function access="public" threadsafety="unspecified" status="commendable" name="pause" fullname="QtServiceController::pause" href="qtservicecontroller.html#pause" location="qtservice_win.cpp" virtual="non" meta="plain" const="false" static="false" overload="false" type="bool" signature="pause()"/>
  32 + <function access="public" threadsafety="unspecified" status="commendable" name="resume" fullname="QtServiceController::resume" href="qtservicecontroller.html#resume" location="qtservice_win.cpp" virtual="non" meta="plain" const="false" static="false" overload="false" type="bool" signature="resume()"/>
  33 + <function access="public" threadsafety="unspecified" status="commendable" name="sendCommand" fullname="QtServiceController::sendCommand" href="qtservicecontroller.html#sendCommand" location="qtservice_win.cpp" virtual="non" meta="plain" const="false" static="false" overload="false" type="bool" signature="sendCommand(int code)">
  34 + <parameter left="int" right="" name="code" default=""/>
  35 + </function>
  36 + </class>
  37 + <class access="public" threadsafety="unspecified" status="commendable" name="QtServiceBase" href="qtservicebase.html" location="qtservice.h" bases="" module="">
  38 + <target name="servicespecificarguments"/>
  39 + <enum access="public" threadsafety="unspecified" status="commendable" name="MessageType" fullname="QtServiceBase::MessageType" href="qtservicebase.html#MessageType-enum" location="qtservice.h">
  40 + <value name="Success" value="0"/>
  41 + <value name="Error" value="1"/>
  42 + <value name="Warning" value="2"/>
  43 + <value name="Information" value="3"/>
  44 + </enum>
  45 + <enum access="public" threadsafety="unspecified" status="commendable" name="ServiceFlag" fullname="QtServiceBase::ServiceFlag" href="qtservicebase.html#ServiceFlag-enum" location="qtservice.h" typedef="QtServiceBase::ServiceFlags">
  46 + <value name="Default" value="0x00"/>
  47 + <value name="CanBeSuspended" value="0x01"/>
  48 + <value name="CannotBeStopped" value="0x02"/>
  49 + <value name="NeedsStopOnShutdown" value="0x04"/>
  50 + </enum>
  51 + <typedef access="public" threadsafety="unspecified" status="commendable" name="ServiceFlags" fullname="QtServiceBase::ServiceFlags" href="qtservicebase.html#ServiceFlags-typedef" location="qtservice.h" enum="QtServiceBase::ServiceFlag"/>
  52 + <function access="public" threadsafety="unspecified" status="commendable" name="QtServiceBase" fullname="QtServiceBase::QtServiceBase" href="qtservicebase.html#QtServiceBase" location="qtservice.h" virtual="non" meta="constructor" const="false" static="false" overload="false" type="" signature="QtServiceBase(int argc, char ** argv, const QString &amp; name)">
  53 + <parameter left="int" right="" name="argc" default=""/>
  54 + <parameter left="char **" right="" name="argv" default=""/>
  55 + <parameter left="const QString &amp;" right="" name="name" default=""/>
  56 + </function>
  57 + <function access="public" threadsafety="unspecified" status="commendable" name="~QtServiceBase" fullname="QtServiceBase::~QtServiceBase" href="qtservicebase.html#dtor.QtServiceBase" location="qtservice.h" virtual="impure" meta="destructor" const="false" static="false" overload="false" type="" signature="~QtServiceBase()"/>
  58 + <function access="public" threadsafety="unspecified" status="commendable" name="serviceName" fullname="QtServiceBase::serviceName" href="qtservicebase.html#serviceName" location="qtservice.h" virtual="non" meta="plain" const="true" static="false" overload="false" type="QString" signature="serviceName() const"/>
  59 + <function access="public" threadsafety="unspecified" status="commendable" name="serviceDescription" fullname="QtServiceBase::serviceDescription" href="qtservicebase.html#serviceDescription" location="qtservice.h" virtual="non" meta="plain" const="true" static="false" overload="false" type="QString" signature="serviceDescription() const"/>
  60 + <function access="public" threadsafety="unspecified" status="commendable" name="setServiceDescription" fullname="QtServiceBase::setServiceDescription" href="qtservicebase.html#setServiceDescription" location="qtservice.h" virtual="non" meta="plain" const="false" static="false" overload="false" type="void" signature="setServiceDescription(const QString &amp; description)">
  61 + <parameter left="const QString &amp;" right="" name="description" default=""/>
  62 + </function>
  63 + <function access="public" threadsafety="unspecified" status="commendable" name="startupType" fullname="QtServiceBase::startupType" href="qtservicebase.html#startupType" location="qtservice.h" virtual="non" meta="plain" const="true" static="false" overload="false" type="QtServiceController::StartupType" signature="startupType() const"/>
  64 + <function access="public" threadsafety="unspecified" status="commendable" name="setStartupType" fullname="QtServiceBase::setStartupType" href="qtservicebase.html#setStartupType" location="qtservice.h" virtual="non" meta="plain" const="false" static="false" overload="false" type="void" signature="setStartupType(QtServiceController::StartupType type)">
  65 + <parameter left="QtServiceController::StartupType" right="" name="type" default=""/>
  66 + </function>
  67 + <function access="public" threadsafety="unspecified" status="commendable" name="serviceFlags" fullname="QtServiceBase::serviceFlags" href="qtservicebase.html#serviceFlags" location="qtservice.h" virtual="non" meta="plain" const="true" static="false" overload="false" type="ServiceFlags" signature="serviceFlags() const"/>
  68 + <function access="public" threadsafety="unspecified" status="commendable" name="setServiceFlags" fullname="QtServiceBase::setServiceFlags" href="qtservicebase.html#setServiceFlags" location="qtservice_win.cpp" virtual="non" meta="plain" const="false" static="false" overload="false" type="void" signature="setServiceFlags(QFlags&lt;QtServiceBase::ServiceFlag&gt; flags)">
  69 + <parameter left="QFlags&lt;QtServiceBase::ServiceFlag&gt;" right="" name="flags" default=""/>
  70 + </function>
  71 + <function access="public" threadsafety="unspecified" status="commendable" name="exec" fullname="QtServiceBase::exec" href="qtservicebase.html#exec" location="qtservice.h" virtual="non" meta="plain" const="false" static="false" overload="false" type="int" signature="exec()"/>
  72 + <function access="public" threadsafety="unspecified" status="commendable" name="logMessage" fullname="QtServiceBase::logMessage" href="qtservicebase.html#logMessage" location="qtservice_win.cpp" virtual="non" meta="plain" const="false" static="false" overload="false" type="void" signature="logMessage(const QString &amp; message, MessageType type, int id, uint category, const QByteArray &amp; data)">
  73 + <parameter left="const QString &amp;" right="" name="message" default=""/>
  74 + <parameter left="MessageType" right="" name="type" default="Success"/>
  75 + <parameter left="int" right="" name="id" default="0"/>
  76 + <parameter left="uint" right="" name="category" default="0"/>
  77 + <parameter left="const QByteArray &amp;" right="" name="data" default="QByteArray()"/>
  78 + </function>
  79 + <function access="public" threadsafety="unspecified" status="commendable" name="instance" fullname="QtServiceBase::instance" href="qtservicebase.html#instance" location="qtservice.h" virtual="non" meta="plain" const="false" static="true" overload="false" type="QtServiceBase *" signature="instance()"/>
  80 + <function access="protected" threadsafety="unspecified" status="commendable" name="start" fullname="QtServiceBase::start" href="qtservicebase.html#start" location="qtservice.h" virtual="pure" meta="plain" const="false" static="false" overload="false" type="void" signature="start()"/>
  81 + <function access="protected" threadsafety="unspecified" status="commendable" name="stop" fullname="QtServiceBase::stop" href="qtservicebase.html#stop" location="qtservice.h" virtual="impure" meta="plain" const="false" static="false" overload="false" type="void" signature="stop()"/>
  82 + <function access="protected" threadsafety="unspecified" status="commendable" name="pause" fullname="QtServiceBase::pause" href="qtservicebase.html#pause" location="qtservice.h" virtual="impure" meta="plain" const="false" static="false" overload="false" type="void" signature="pause()"/>
  83 + <function access="protected" threadsafety="unspecified" status="commendable" name="resume" fullname="QtServiceBase::resume" href="qtservicebase.html#resume" location="qtservice.h" virtual="impure" meta="plain" const="false" static="false" overload="false" type="void" signature="resume()"/>
  84 + <function access="protected" threadsafety="unspecified" status="commendable" name="processCommand" fullname="QtServiceBase::processCommand" href="qtservicebase.html#processCommand" location="qtservice.h" virtual="impure" meta="plain" const="false" static="false" overload="false" type="void" signature="processCommand(int code)">
  85 + <parameter left="int" right="" name="code" default=""/>
  86 + </function>
  87 + <function access="protected" threadsafety="unspecified" status="commendable" name="createApplication" fullname="QtServiceBase::createApplication" href="qtservicebase.html#createApplication" location="qtservice.h" virtual="pure" meta="plain" const="false" static="false" overload="false" type="void" signature="createApplication(int &amp; argc, char ** argv)">
  88 + <parameter left="int &amp;" right="" name="argc" default=""/>
  89 + <parameter left="char **" right="" name="argv" default=""/>
  90 + </function>
  91 + <function access="protected" threadsafety="unspecified" status="commendable" name="executeApplication" fullname="QtServiceBase::executeApplication" href="qtservicebase.html#executeApplication" location="qtservice.h" virtual="pure" meta="plain" const="false" static="false" overload="false" type="int" signature="executeApplication()"/>
  92 + </class>
  93 + <class access="public" threadsafety="unspecified" status="commendable" name="QtService" href="qtservice.html" location="qtservice.h" bases="QtServiceBase" module="">
  94 + <function access="public" threadsafety="unspecified" status="commendable" name="QtService" fullname="QtService::QtService" href="qtservice.html#QtService" location="qtservice.h" virtual="non" meta="constructor" const="false" static="false" overload="false" type="" signature="QtService(int argc, char ** argv, const QString &amp; name)">
  95 + <parameter left="int" right="" name="argc" default=""/>
  96 + <parameter left="char **" right="" name="argv" default=""/>
  97 + <parameter left="const QString &amp;" right="" name="name" default=""/>
  98 + </function>
  99 + <function access="public" threadsafety="unspecified" status="commendable" name="~QtService" fullname="QtService::~QtService" href="qtservice.html#dtor.QtService" location="qtservice.h" virtual="non" meta="destructor" const="false" static="false" overload="false" type="" signature="~QtService()"/>
  100 + <function access="protected" threadsafety="unspecified" status="commendable" name="application" fullname="QtService::application" href="qtservice.html#application" location="qtservice.h" virtual="non" meta="plain" const="true" static="false" overload="false" type="Application *" signature="application() const"/>
  101 + <function access="protected" threadsafety="unspecified" status="commendable" name="createApplication" fullname="QtService::createApplication" href="qtservice.html#createApplication" location="qtservice.h" virtual="impure" meta="plain" const="false" static="false" overload="false" type="void" signature="createApplication(int &amp; argc, char ** argv)">
  102 + <parameter left="int &amp;" right="" name="argc" default=""/>
  103 + <parameter left="char **" right="" name="argv" default=""/>
  104 + </function>
  105 + <function access="protected" threadsafety="unspecified" status="commendable" name="executeApplication" fullname="QtService::executeApplication" href="qtservice.html#executeApplication" location="qtservice.h" virtual="impure" meta="plain" const="false" static="false" overload="false" type="int" signature="executeApplication()"/>
  106 + </class>
  107 + <page access="public" status="commendable" name="index.html" href="index.html" subtype="page" title="Service" fulltitle="Service" subtitle="" location="index.qdoc">
  108 + <contents name="description" title="Description" level="1"/>
  109 + <contents name="classes" title="Classes" level="1"/>
  110 + <contents name="examples" title="Examples" level="1"/>
  111 + <contents name="tested-platforms" title="Tested platforms" level="1"/>
  112 + </page>
  113 + <page access="public" status="commendable" name="qtservice-example-controller.html" href="qtservice-example-controller.html" subtype="page" title="A simple Service Controller" fulltitle="A simple Service Controller" subtitle="" location="controller.qdoc"/>
  114 + <page access="public" status="commendable" name="qtservice-example-interactive.html" href="qtservice-example-interactive.html" subtype="page" title="An Interactive Service" fulltitle="An Interactive Service" subtitle="" location="interactive.qdoc"/>
  115 + <page access="public" status="commendable" name="qtservice-example-server.html" href="qtservice-example-server.html" subtype="page" title="A simple HTTP Server" fulltitle="A simple HTTP Server" subtitle="" location="server.qdoc"/>
  116 + </namespace>
  117 +</INDEX>
... ...
src/qtservice/doc/html/qtservice.qhp 0 → 100644
... ... @@ -0,0 +1,93 @@
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<QtHelpProject version="1.0">
  3 + <namespace>com.nokia.qtsolutions.qtservice_head</namespace>
  4 + <virtualFolder>qdoc</virtualFolder>
  5 + <customFilter name="Qt Solutions: Service">
  6 + <filterAttribute>qt</filterAttribute>
  7 + <filterAttribute>qtservice</filterAttribute>
  8 + <filterAttribute>solutions</filterAttribute>
  9 + </customFilter>
  10 + <filterSection>
  11 + <filterAttribute>qt</filterAttribute>
  12 + <filterAttribute>qtservice</filterAttribute>
  13 + <filterAttribute>solutions</filterAttribute>
  14 + <toc>
  15 + <section ref="index.html" title="Qt Solutions: Service Documentation">
  16 + <section ref="qtservice-example-server.html" title="A simple HTTP Server"/>
  17 + <section ref="qtservice-example-controller.html" title="A simple Service Controller"/>
  18 + <section ref="qtservice-example-interactive.html" title="An Interactive Service"/>
  19 + <section ref="index.html" title="Service"/>
  20 + </section>
  21 + </toc>
  22 + <keywords>
  23 + <keyword name="A simple HTTP Server" id="A simple HTTP Server" ref="qtservice-example-server.html"/>
  24 + <keyword name="A simple Service Controller" id="A simple Service Controller" ref="qtservice-example-controller.html"/>
  25 + <keyword name="An Interactive Service" id="An Interactive Service" ref="qtservice-example-interactive.html"/>
  26 + <keyword name="QtService" id="QtService" ref="qtservice.html"/>
  27 + <keyword name="application" id="QtService::application" ref="qtservice.html#application"/>
  28 + <keyword name="createApplication" id="QtService::createApplication" ref="qtservice.html#createApplication"/>
  29 + <keyword name="executeApplication" id="QtService::executeApplication" ref="qtservice.html#executeApplication"/>
  30 + <keyword name="~QtService" id="QtService::~QtService" ref="qtservice.html#dtor.QtService"/>
  31 + <keyword name="QtServiceBase" id="QtServiceBase" ref="qtservicebase.html"/>
  32 + <keyword name="QtServiceBase::MessageType" id="QtServiceBase::MessageType" ref="qtservicebase.html#MessageType-enum"/>
  33 + <keyword name="QtServiceBase::Success" id="QtServiceBase::Success" ref="qtservicebase.html#MessageType-enum"/>
  34 + <keyword name="QtServiceBase::Error" id="QtServiceBase::Error" ref="qtservicebase.html#MessageType-enum"/>
  35 + <keyword name="QtServiceBase::Warning" id="QtServiceBase::Warning" ref="qtservicebase.html#MessageType-enum"/>
  36 + <keyword name="QtServiceBase::Information" id="QtServiceBase::Information" ref="qtservicebase.html#MessageType-enum"/>
  37 + <keyword name="QtServiceBase::ServiceFlag" id="QtServiceBase::ServiceFlag" ref="qtservicebase.html#ServiceFlag-enum"/>
  38 + <keyword name="QtServiceBase::Default" id="QtServiceBase::Default" ref="qtservicebase.html#ServiceFlag-enum"/>
  39 + <keyword name="QtServiceBase::CanBeSuspended" id="QtServiceBase::CanBeSuspended" ref="qtservicebase.html#ServiceFlag-enum"/>
  40 + <keyword name="QtServiceBase::CannotBeStopped" id="QtServiceBase::CannotBeStopped" ref="qtservicebase.html#ServiceFlag-enum"/>
  41 + <keyword name="QtServiceBase::NeedsStopOnShutdown" id="QtServiceBase::NeedsStopOnShutdown" ref="qtservicebase.html#ServiceFlag-enum"/>
  42 + <keyword name="QtServiceBase::ServiceFlags" id="QtServiceBase::ServiceFlags" ref="qtservicebase.html#ServiceFlag-enum"/>
  43 + <keyword name="createApplication" id="QtServiceBase::createApplication" ref="qtservicebase.html#createApplication"/>
  44 + <keyword name="exec" id="QtServiceBase::exec" ref="qtservicebase.html#exec"/>
  45 + <keyword name="executeApplication" id="QtServiceBase::executeApplication" ref="qtservicebase.html#executeApplication"/>
  46 + <keyword name="instance" id="QtServiceBase::instance" ref="qtservicebase.html#instance"/>
  47 + <keyword name="logMessage" id="QtServiceBase::logMessage" ref="qtservicebase.html#logMessage"/>
  48 + <keyword name="pause" id="QtServiceBase::pause" ref="qtservicebase.html#pause"/>
  49 + <keyword name="processCommand" id="QtServiceBase::processCommand" ref="qtservicebase.html#processCommand"/>
  50 + <keyword name="resume" id="QtServiceBase::resume" ref="qtservicebase.html#resume"/>
  51 + <keyword name="serviceDescription" id="QtServiceBase::serviceDescription" ref="qtservicebase.html#serviceDescription"/>
  52 + <keyword name="serviceFlags" id="QtServiceBase::serviceFlags" ref="qtservicebase.html#serviceFlags"/>
  53 + <keyword name="serviceName" id="QtServiceBase::serviceName" ref="qtservicebase.html#serviceName"/>
  54 + <keyword name="setServiceDescription" id="QtServiceBase::setServiceDescription" ref="qtservicebase.html#setServiceDescription"/>
  55 + <keyword name="setServiceFlags" id="QtServiceBase::setServiceFlags" ref="qtservicebase.html#setServiceFlags"/>
  56 + <keyword name="setStartupType" id="QtServiceBase::setStartupType" ref="qtservicebase.html#setStartupType"/>
  57 + <keyword name="start" id="QtServiceBase::start" ref="qtservicebase.html#start"/>
  58 + <keyword name="startupType" id="QtServiceBase::startupType" ref="qtservicebase.html#startupType"/>
  59 + <keyword name="stop" id="QtServiceBase::stop" ref="qtservicebase.html#stop"/>
  60 + <keyword name="~QtServiceBase" id="QtServiceBase::~QtServiceBase" ref="qtservicebase.html#dtor.QtServiceBase"/>
  61 + <keyword name="QtServiceController" id="QtServiceController" ref="qtservicecontroller.html"/>
  62 + <keyword name="QtServiceController::StartupType" id="QtServiceController::StartupType" ref="qtservicecontroller.html#StartupType-enum"/>
  63 + <keyword name="QtServiceController::AutoStartup" id="QtServiceController::AutoStartup" ref="qtservicecontroller.html#StartupType-enum"/>
  64 + <keyword name="QtServiceController::ManualStartup" id="QtServiceController::ManualStartup" ref="qtservicecontroller.html#StartupType-enum"/>
  65 + <keyword name="install" id="QtServiceController::install" ref="qtservicecontroller.html#install"/>
  66 + <keyword name="isInstalled" id="QtServiceController::isInstalled" ref="qtservicecontroller.html#isInstalled"/>
  67 + <keyword name="isRunning" id="QtServiceController::isRunning" ref="qtservicecontroller.html#isRunning"/>
  68 + <keyword name="pause" id="QtServiceController::pause" ref="qtservicecontroller.html#pause"/>
  69 + <keyword name="resume" id="QtServiceController::resume" ref="qtservicecontroller.html#resume"/>
  70 + <keyword name="sendCommand" id="QtServiceController::sendCommand" ref="qtservicecontroller.html#sendCommand"/>
  71 + <keyword name="serviceDescription" id="QtServiceController::serviceDescription" ref="qtservicecontroller.html#serviceDescription"/>
  72 + <keyword name="serviceFilePath" id="QtServiceController::serviceFilePath" ref="qtservicecontroller.html#serviceFilePath"/>
  73 + <keyword name="serviceName" id="QtServiceController::serviceName" ref="qtservicecontroller.html#serviceName"/>
  74 + <keyword name="start" id="QtServiceController::start" ref="qtservicecontroller.html#start"/>
  75 + <keyword name="startupType" id="QtServiceController::startupType" ref="qtservicecontroller.html#startupType"/>
  76 + <keyword name="stop" id="QtServiceController::stop" ref="qtservicecontroller.html#stop"/>
  77 + <keyword name="uninstall" id="QtServiceController::uninstall" ref="qtservicecontroller.html#uninstall"/>
  78 + <keyword name="~QtServiceController" id="QtServiceController::~QtServiceController" ref="qtservicecontroller.html#dtor.QtServiceController"/>
  79 + <keyword name="Service" id="Service" ref="index.html"/>
  80 + </keywords>
  81 + <files>
  82 + <file>qtservice-example-controller.html</file>
  83 + <file>index.html</file>
  84 + <file>qtservice-example-server.html</file>
  85 + <file>qtservice-example-interactive.html</file>
  86 + <file>qtservicebase.html</file>
  87 + <file>qtservice.html</file>
  88 + <file>qtservicecontroller.html</file>
  89 + <file>classic.css</file>
  90 + <file>images/qt-logo.png</file>
  91 + </files>
  92 + </filterSection>
  93 +</QtHelpProject>
... ...
src/qtservice/doc/html/qtservicebase-members.html 0 → 100644
... ... @@ -0,0 +1,51 @@
  1 +<?xml version="1.0" encoding="iso-8859-1"?>
  2 +<!DOCTYPE html
  3 + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 +<!-- qtservice.cpp -->
  6 +<head>
  7 + <title>List of All Members for QtServiceBase</title>
  8 + <link href="classic.css" rel="stylesheet" type="text/css" />
  9 +</head>
  10 +<body>
  11 +<table border="0" cellpadding="0" cellspacing="0" width="100%">
  12 +<tr>
  13 +<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="57" height="67" border="0" /></td>
  14 +<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a></td>
  15 +</tr></table><h1 class="title">List of All Members for QtServiceBase</h1>
  16 +<p>This is the complete list of members for <a href="qtservicebase.html">QtServiceBase</a>, including inherited members.</p>
  17 +<p><table class="propsummary" width="100%" border="0" cellpadding="0" cellspacing="0">
  18 +<tr><td width="45%" valign="top"><ul>
  19 +<li><div class="fn">enum <b><a href="qtservicebase.html#MessageType-enum">MessageType</a></b></div></li>
  20 +<li><div class="fn">enum <b><a href="qtservicebase.html#ServiceFlag-enum">ServiceFlag</a></b></div></li>
  21 +<li><div class="fn">flags <b><a href="qtservicebase.html#ServiceFlag-enum">ServiceFlags</a></b></div></li>
  22 +<li><div class="fn"><b><a href="qtservicebase.html#QtServiceBase">QtServiceBase</a></b> ( int, char **, const QString &amp; )</div></li>
  23 +<li><div class="fn"><b><a href="qtservicebase.html#dtor.QtServiceBase">~QtServiceBase</a></b> ()</div></li>
  24 +<li><div class="fn"><b><a href="qtservicebase.html#createApplication">createApplication</a></b> ( int &amp;, char ** )</div></li>
  25 +<li><div class="fn"><b><a href="qtservicebase.html#exec">exec</a></b> () : int</div></li>
  26 +<li><div class="fn"><b><a href="qtservicebase.html#executeApplication">executeApplication</a></b> () : int</div></li>
  27 +<li><div class="fn"><b><a href="qtservicebase.html#instance">instance</a></b> () : QtServiceBase *</div></li>
  28 +<li><div class="fn"><b><a href="qtservicebase.html#logMessage">logMessage</a></b> ( const QString &amp;, MessageType, int, uint, const QByteArray &amp; )</div></li>
  29 +<li><div class="fn"><b><a href="qtservicebase.html#pause">pause</a></b> ()</div></li>
  30 +</ul></td><td valign="top"><ul>
  31 +<li><div class="fn"><b><a href="qtservicebase.html#processCommand">processCommand</a></b> ( int )</div></li>
  32 +<li><div class="fn"><b><a href="qtservicebase.html#resume">resume</a></b> ()</div></li>
  33 +<li><div class="fn"><b><a href="qtservicebase.html#serviceDescription">serviceDescription</a></b> () const : QString</div></li>
  34 +<li><div class="fn"><b><a href="qtservicebase.html#serviceFlags">serviceFlags</a></b> () const : ServiceFlags</div></li>
  35 +<li><div class="fn"><b><a href="qtservicebase.html#serviceName">serviceName</a></b> () const : QString</div></li>
  36 +<li><div class="fn"><b><a href="qtservicebase.html#setServiceDescription">setServiceDescription</a></b> ( const QString &amp; )</div></li>
  37 +<li><div class="fn"><b><a href="qtservicebase.html#setServiceFlags">setServiceFlags</a></b> ( ServiceFlags )</div></li>
  38 +<li><div class="fn"><b><a href="qtservicebase.html#setStartupType">setStartupType</a></b> ( QtServiceController::StartupType )</div></li>
  39 +<li><div class="fn"><b><a href="qtservicebase.html#start">start</a></b> ()</div></li>
  40 +<li><div class="fn"><b><a href="qtservicebase.html#startupType">startupType</a></b> () const : QtServiceController::StartupType</div></li>
  41 +<li><div class="fn"><b><a href="qtservicebase.html#stop">stop</a></b> ()</div></li>
  42 +</ul>
  43 +</td></tr>
  44 +</table></p>
  45 +<p /><address><hr /><div align="center">
  46 +<table width="100%" cellspacing="0" border="0"><tr class="address">
  47 +<td width="30%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
  48 +<td width="40%" align="center"><a href="http://qt.nokia.com/doc/trademarks.html">Trademarks</a></td>
  49 +<td width="30%" align="right"><div align="right">Qt Solutions</div></td>
  50 +</tr></table></div></address></body>
  51 +</html>
... ...
src/qtservice/doc/html/qtservicebase.html 0 → 100644
... ... @@ -0,0 +1,204 @@
  1 +<?xml version="1.0" encoding="iso-8859-1"?>
  2 +<!DOCTYPE html
  3 + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 +<!-- qtservice.cpp -->
  6 +<head>
  7 + <title>QtServiceBase Class Reference</title>
  8 + <link href="classic.css" rel="stylesheet" type="text/css" />
  9 +</head>
  10 +<body>
  11 +<table border="0" cellpadding="0" cellspacing="0" width="100%">
  12 +<tr>
  13 +<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="57" height="67" border="0" /></td>
  14 +<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a></td>
  15 +</tr></table><h1 class="title">QtServiceBase Class Reference</h1>
  16 +<p>The QtServiceBase class provides an API for implementing Windows services and Unix daemons. <a href="#details">More...</a></p>
  17 +<pre> #include &lt;QtServiceBase&gt;</pre><p>Inherited by <a href="qtservice.html">QtService</a>.</p>
  18 +<ul>
  19 +<li><a href="qtservicebase-members.html">List of all members, including inherited members</a></li>
  20 +</ul>
  21 +<hr />
  22 +<a name="public-types"></a>
  23 +<h2>Public Types</h2>
  24 +<table class="alignedsummary" border="0" cellpadding="0" cellspacing="0" width="100%">
  25 +<tr><td class="memItemLeft" align="right" valign="top">enum </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#MessageType-enum">MessageType</a></b> { Success, Error, Warning, Information }</td></tr>
  26 +<tr><td class="memItemLeft" align="right" valign="top">enum </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#ServiceFlag-enum">ServiceFlag</a></b> { Default, CanBeSuspended, CannotBeStopped, NeedsStopOnShutdown }</td></tr>
  27 +<tr><td class="memItemLeft" align="right" valign="top">flags </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#ServiceFlag-enum">ServiceFlags</a></b></td></tr>
  28 +</table>
  29 +<hr />
  30 +<a name="public-functions"></a>
  31 +<h2>Public Functions</h2>
  32 +<table class="alignedsummary" border="0" cellpadding="0" cellspacing="0" width="100%">
  33 +<tr><td class="memItemLeft" align="right" valign="top"></td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#QtServiceBase">QtServiceBase</a></b> ( int <i>argc</i>, char ** <i>argv</i>, const QString &amp; <i>name</i> )</td></tr>
  34 +<tr><td class="memItemLeft" align="right" valign="top">virtual </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#dtor.QtServiceBase">~QtServiceBase</a></b> ()</td></tr>
  35 +<tr><td class="memItemLeft" align="right" valign="top">int </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#exec">exec</a></b> ()</td></tr>
  36 +<tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#logMessage">logMessage</a></b> ( const QString &amp; <i>message</i>, MessageType <i>type</i> = Success, int <i>id</i> = 0, uint <i>category</i> = 0, const QByteArray &amp; <i>data</i> = QByteArray() )</td></tr>
  37 +<tr><td class="memItemLeft" align="right" valign="top">QString </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#serviceDescription">serviceDescription</a></b> () const</td></tr>
  38 +<tr><td class="memItemLeft" align="right" valign="top">ServiceFlags </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#serviceFlags">serviceFlags</a></b> () const</td></tr>
  39 +<tr><td class="memItemLeft" align="right" valign="top">QString </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#serviceName">serviceName</a></b> () const</td></tr>
  40 +<tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#setServiceDescription">setServiceDescription</a></b> ( const QString &amp; <i>description</i> )</td></tr>
  41 +<tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#setServiceFlags">setServiceFlags</a></b> ( ServiceFlags <i>flags</i> )</td></tr>
  42 +<tr><td class="memItemLeft" align="right" valign="top">void </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#setStartupType">setStartupType</a></b> ( QtServiceController::StartupType <i>type</i> )</td></tr>
  43 +<tr><td class="memItemLeft" align="right" valign="top">QtServiceController::StartupType </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#startupType">startupType</a></b> () const</td></tr>
  44 +</table>
  45 +<hr />
  46 +<a name="static-public-members"></a>
  47 +<h2>Static Public Members</h2>
  48 +<table class="alignedsummary" border="0" cellpadding="0" cellspacing="0" width="100%">
  49 +<tr><td class="memItemLeft" align="right" valign="top">QtServiceBase * </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#instance">instance</a></b> ()</td></tr>
  50 +</table>
  51 +<hr />
  52 +<a name="protected-functions"></a>
  53 +<h2>Protected Functions</h2>
  54 +<table class="alignedsummary" border="0" cellpadding="0" cellspacing="0" width="100%">
  55 +<tr><td class="memItemLeft" align="right" valign="top">virtual void </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#createApplication">createApplication</a></b> ( int &amp; <i>argc</i>, char ** <i>argv</i> ) = 0</td></tr>
  56 +<tr><td class="memItemLeft" align="right" valign="top">virtual int </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#executeApplication">executeApplication</a></b> () = 0</td></tr>
  57 +<tr><td class="memItemLeft" align="right" valign="top">virtual void </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#pause">pause</a></b> ()</td></tr>
  58 +<tr><td class="memItemLeft" align="right" valign="top">virtual void </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#processCommand">processCommand</a></b> ( int <i>code</i> )</td></tr>
  59 +<tr><td class="memItemLeft" align="right" valign="top">virtual void </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#resume">resume</a></b> ()</td></tr>
  60 +<tr><td class="memItemLeft" align="right" valign="top">virtual void </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#start">start</a></b> () = 0</td></tr>
  61 +<tr><td class="memItemLeft" align="right" valign="top">virtual void </td><td class="memItemRight" valign="bottom"><b><a href="qtservicebase.html#stop">stop</a></b> ()</td></tr>
  62 +</table>
  63 +<a name="details"></a>
  64 +<hr />
  65 +<h2>Detailed Description</h2>
  66 +<p>The QtServiceBase class provides an API for implementing Windows services and Unix daemons.</p>
  67 +<p>A Windows service or Unix daemon (a &quot;service&quot;), is a program that runs &quot;in the background&quot; 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.</p>
  68 +<p>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, <a href="qtservicecontroller.html#sendCommand">QtServiceController::sendCommand</a>() and <a href="qtservicebase.html#processCommand">QtService::processCommand</a>() 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&#x2e; based on Qt's networking classes. (In certain circumstances, a service may provide a GUI itself, ref. the &quot;interactive&quot; example documentation).</p>
  69 +<p>Typically, you will create a service by subclassing the <a href="qtservice.html">QtService</a> template class which inherits QtServiceBase and allows you to create a service for a particular application type.</p>
  70 +<p>The Windows implementation uses the NT Service Control Manager, and the application can be controlled through the system administration tools. Services are usually launched using the system account, which requires that all DLLs that the service executable depends on (i.e&#x2e; Qt), are located in the same directory as the service, or in a system path.</p>
  71 +<p>On Unix a service is implemented as a daemon.</p>
  72 +<p>You can retrieve the service's description, state, and startup type using the <a href="qtservicebase.html#serviceDescription">serviceDescription</a>(), <a href="qtservicebase.html#serviceFlags">serviceFlags</a>() and <a href="qtservicebase.html#startupType">startupType</a>() functions respectively. The service's state is decribed by the <a href="qtservicebase.html#ServiceFlag-enum">ServiceFlag</a> enum. The mentioned properites can also be set using the corresponding set functions. In addition you can retrieve the service's name using the <a href="qtservicebase.html#serviceName">serviceName</a>() function.</p>
  73 +<p>Several of QtServiceBase's protected functions are called on requests from the <a href="qtservicecontroller.html">QtServiceController</a> class:</p>
  74 +<ul>
  75 +<li><a href="qtservicebase.html#start">start</a>()</li>
  76 +<li><a href="qtservicebase.html#pause">pause</a>()</li>
  77 +<li><a href="qtservicebase.html#processCommand">processCommand</a>()</li>
  78 +<li><a href="qtservicebase.html#resume">resume</a>()</li>
  79 +<li><a href="qtservicebase.html#stop">stop</a>()</li>
  80 +</ul>
  81 +<p>You can control any given service using an instance of the <a href="qtservicecontroller.html">QtServiceController</a> 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. You can reimplement these functions to pause and resume the service's execution, as well as process user commands and perform additional clean-ups before shutting down.</p>
  82 +<p>QtServiceBase also provides the static <a href="qtservicebase.html#instance">instance</a>() function which returns a pointer to an application's QtServiceBase instance. In addition, a service can report events to the system's event log using the <a href="qtservicebase.html#logMessage">logMessage</a>() function. The <a href="qtservicebase.html#MessageType-enum">MessageType</a> enum describes the different types of messages a service reports.</p>
  83 +<p>The implementation of a service application's main function typically creates an service object derived by subclassing the <a href="qtservice.html">QtService</a> template class. Then the main function will call this service's <a href="qtservicebase.html#exec">exec</a>() function, and return the result of that call. For example:</p>
  84 +<pre> int main(int argc, char **argv)
  85 + {
  86 + MyService service(argc, argv);
  87 + return service.exec();
  88 + }</pre>
  89 +<p>When the <a href="qtservicebase.html#exec">exec</a>() function is called, it will parse the service specific arguments passed in <tt>argv</tt>, perform the required actions, and return.</p>
  90 +<a name="servicespecificarguments"></a><p>The following arguments are recognized as service specific:</p>
  91 +<p><table class="generic" align="center" cellpadding="2" cellspacing="1" border="0">
  92 +<thead><tr valign="top" class="qt-style"><th>Short</th><th>Long</th><th>Explanation</th></tr></thead>
  93 +<tr valign="top" class="odd"><td>-i</td><td>-install</td><td>Install the service.</td></tr>
  94 +<tr valign="top" class="even"><td>-u</td><td>-uninstall</td><td>Uninstall the service.</td></tr>
  95 +<tr valign="top" class="odd"><td>-e</td><td>-exec</td><td>Execute the service as a standalone application (useful for debug purposes). This is a blocking call, the service will be executed like a normal application. In this mode you will not be able to communicate with the service from the contoller.</td></tr>
  96 +<tr valign="top" class="even"><td>-t</td><td>-terminate</td><td>Stop the service.</td></tr>
  97 +<tr valign="top" class="odd"><td>-p</td><td>-pause</td><td>Pause the service.</td></tr>
  98 +<tr valign="top" class="even"><td>-r</td><td>-resume</td><td>Resume a paused service.</td></tr>
  99 +<tr valign="top" class="odd"><td>-c <i>cmd</i></td><td>-command <i>cmd</i></td><td>Send the user defined command code <i>cmd</i> to the service application.</td></tr>
  100 +<tr valign="top" class="even"><td>-v</td><td>-version</td><td>Display version and status information.</td></tr>
  101 +</table></p>
  102 +<p>If <i>none</i> of the arguments is recognized as service specific, <a href="qtservicebase.html#exec">exec</a>() will first call the <a href="qtservicebase.html#createApplication">createApplication</a>() function, then <a href="qtservicebase.html#executeApplication">executeApplication</a>() and finally the <a href="qtservicebase.html#start">start</a>() function. In the end, <a href="qtservicebase.html#exec">exec</a>() returns while the service continues in its own process waiting for commands from the service controller.</p>
  103 +<p>See also <a href="qtservice.html">QtService</a> and <a href="qtservicecontroller.html">QtServiceController</a>.</p>
  104 +<hr />
  105 +<h2>Member Type Documentation</h2>
  106 +<h3 class="fn"><a name="MessageType-enum"></a>enum QtServiceBase::MessageType</h3>
  107 +<p>This enum describes the different types of messages a service reports to the system log.</p>
  108 +<p><table class="valuelist" border="1" cellpadding="2" cellspacing="1" width="100%">
  109 +<tr><th width="25%">Constant</th><th width="15%">Value</th><th width="60%">Description</th></tr>
  110 +<tr><td valign="top"><tt>QtServiceBase::Success</tt></td><td align="center" valign="top"><tt>0</tt></td><td valign="top">An operation has succeeded, e.g&#x2e; the service is started.</td></tr>
  111 +<tr><td valign="top"><tt>QtServiceBase::Error</tt></td><td align="center" valign="top"><tt>1</tt></td><td valign="top">An operation failed, e.g&#x2e; the service failed to start.</td></tr>
  112 +<tr><td valign="top"><tt>QtServiceBase::Warning</tt></td><td align="center" valign="top"><tt>2</tt></td><td valign="top">An operation caused a warning that might require user interaction.</td></tr>
  113 +<tr><td valign="top"><tt>QtServiceBase::Information</tt></td><td align="center" valign="top"><tt>3</tt></td><td valign="top">Any type of usually non-critical information.</td></tr>
  114 +</table></p>
  115 +<h3 class="flags"><a name="ServiceFlag-enum"></a>enum QtServiceBase::ServiceFlag<br />flags QtServiceBase::ServiceFlags</h3>
  116 +<p>This enum describes the different capabilities of a service.</p>
  117 +<p><table class="valuelist" border="1" cellpadding="2" cellspacing="1" width="100%">
  118 +<tr><th width="25%">Constant</th><th width="15%">Value</th><th width="60%">Description</th></tr>
  119 +<tr><td valign="top"><tt>QtServiceBase::Default</tt></td><td align="center" valign="top"><tt>0x00</tt></td><td valign="top">The service can be stopped, but not suspended.</td></tr>
  120 +<tr><td valign="top"><tt>QtServiceBase::CanBeSuspended</tt></td><td align="center" valign="top"><tt>0x01</tt></td><td valign="top">The service can be suspended.</td></tr>
  121 +<tr><td valign="top"><tt>QtServiceBase::CannotBeStopped</tt></td><td align="center" valign="top"><tt>0x02</tt></td><td valign="top">The service cannot be stopped.</td></tr>
  122 +<tr><td valign="top"><tt>QtServiceBase::NeedsStopOnShutdown</tt></td><td align="center" valign="top"><tt>0x04</tt></td><td valign="top">(Windows only) The service will be stopped before the system shuts down. Note that Microsoft recommends this only for services that must absolutely clean up during shutdown, because there is a limited time available for shutdown of services.</td></tr>
  123 +</table></p>
  124 +<p>The ServiceFlags type is a typedef for <a href="qflags.html">QFlags</a>&lt;ServiceFlag&gt;. It stores an OR combination of ServiceFlag values.</p>
  125 +<hr />
  126 +<h2>Member Function Documentation</h2>
  127 +<h3 class="fn"><a name="QtServiceBase"></a>QtServiceBase::QtServiceBase ( int <i>argc</i>, char ** <i>argv</i>, const <a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> &amp; <i>name</i> )</h3>
  128 +<p>Creates a service instance called <i>name</i>. The <i>argc</i> and <i>argv</i> parameters are parsed after the <a href="qtservicebase.html#exec">exec</a>() function has been called. Then they are passed to the application's constructor. The application type is determined by the <a href="qtservice.html">QtService</a> subclass.</p>
  129 +<p>The service is neither installed nor started. The name must not contain any backslashes or be longer than 255 characters. In addition, the name must be unique in the system's service database.</p>
  130 +<p>See also <a href="qtservicebase.html#exec">exec</a>(), <a href="qtservicebase.html#start">start</a>(), and <a href="qtservicecontroller.html#install">QtServiceController::install</a>().</p>
  131 +<h3 class="fn"><a name="dtor.QtServiceBase"></a>QtServiceBase::~QtServiceBase ()&nbsp;&nbsp;<tt> [virtual]</tt></h3>
  132 +<p>Destroys the service object. This neither stops nor uninstalls the service.</p>
  133 +<p>To stop a service the <a href="qtservicebase.html#stop">stop</a>() function must be called explicitly. To uninstall a service, you can use the <a href="qtservicecontroller.html#uninstall">QtServiceController::uninstall</a>() function.</p>
  134 +<p>See also <a href="qtservicebase.html#stop">stop</a>() and <a href="qtservicecontroller.html#uninstall">QtServiceController::uninstall</a>().</p>
  135 +<h3 class="fn"><a name="createApplication"></a>void QtServiceBase::createApplication ( int &amp; <i>argc</i>, char ** <i>argv</i> )&nbsp;&nbsp;<tt> [pure virtual protected]</tt></h3>
  136 +<p>Creates the application object using the <i>argc</i> and <i>argv</i> parameters.</p>
  137 +<p>This function is only called when no <a href="qtservicebase.html#servicespecificarguments">service specific arguments</a> were passed to the service constructor, and is called by <a href="qtservicebase.html#exec">exec</a>() before it calls the <a href="qtservicebase.html#executeApplication">executeApplication</a>() and <a href="qtservicebase.html#start">start</a>() functions.</p>
  138 +<p>The createApplication() function is implemented in <a href="qtservice.html">QtService</a>, but you might want to reimplement it, for example, if the chosen application type's constructor needs additional arguments.</p>
  139 +<p>See also <a href="qtservicebase.html#exec">exec</a>() and <a href="qtservice.html">QtService</a>.</p>
  140 +<h3 class="fn"><a name="exec"></a>int QtServiceBase::exec ()</h3>
  141 +<p>Executes the service.</p>
  142 +<p>When the exec() function is called, it will parse the <a href="qtservicebase.html#servicespecificarguments">service specific arguments</a> passed in <tt>argv</tt>, perform the required actions, and exit.</p>
  143 +<p>If none of the arguments is recognized as service specific, exec() will first call the <a href="qtservicebase.html#createApplication">createApplication</a>() function, then <a href="qtservicebase.html#executeApplication">executeApplication</a>() and finally the <a href="qtservicebase.html#start">start</a>() function. In the end, exec() returns while the service continues in its own process waiting for commands from the service controller.</p>
  144 +<p>See also <a href="qtservicecontroller.html">QtServiceController</a>.</p>
  145 +<h3 class="fn"><a name="executeApplication"></a>int QtServiceBase::executeApplication ()&nbsp;&nbsp;<tt> [pure virtual protected]</tt></h3>
  146 +<p>Executes the application previously created with the <a href="qtservicebase.html#createApplication">createApplication</a>() function.</p>
  147 +<p>This function is only called when no <a href="qtservicebase.html#servicespecificarguments">service specific arguments</a> were passed to the service constructor, and is called by <a href="qtservicebase.html#exec">exec</a>() after it has called the <a href="qtservicebase.html#createApplication">createApplication</a>() function and before <a href="qtservicebase.html#start">start</a>() function.</p>
  148 +<p>This function is implemented in <a href="qtservice.html">QtService</a>.</p>
  149 +<p>See also <a href="qtservicebase.html#exec">exec</a>() and <a href="qtservicebase.html#createApplication">createApplication</a>().</p>
  150 +<h3 class="fn"><a name="instance"></a>QtServiceBase * QtServiceBase::instance ()&nbsp;&nbsp;<tt> [static]</tt></h3>
  151 +<p>Returns a pointer to the current application's <a href="qtservicebase.html">QtServiceBase</a> instance.</p>
  152 +<h3 class="fn"><a name="logMessage"></a>void QtServiceBase::logMessage ( const <a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> &amp; <i>message</i>, <a href="qtservicebase.html#MessageType-enum">MessageType</a> <i>type</i> = Success, int <i>id</i> = 0, <a href="http://qt.nokia.com/doc/4.6/qtglobal.html#uint-typedef">uint</a> <i>category</i> = 0, const <a href="http://qt.nokia.com/doc/4.6/qbytearray.html">QByteArray</a> &amp; <i>data</i> = QByteArray() )</h3>
  153 +<p>Reports a message of the given <i>type</i> with the given <i>message</i> to the local system event log. The message identifier <i>id</i> and the message <i>category</i> are user defined values. The <i>data</i> parameter can contain arbitrary binary data.</p>
  154 +<p>Message strings for <i>id</i> and <i>category</i> must be provided by a message file, which must be registered in the system registry. Refer to the MSDN for more information about how to do this on Windows.</p>
  155 +<p>See also <a href="qtservicebase.html#MessageType-enum">MessageType</a>.</p>
  156 +<h3 class="fn"><a name="pause"></a>void QtServiceBase::pause ()&nbsp;&nbsp;<tt> [virtual protected]</tt></h3>
  157 +<p>Reimplement this function to pause the service's execution (for example to stop a polling timer, or to ignore socket notifiers).</p>
  158 +<p>This function is called in reply to controller requests. The default implementation does nothing.</p>
  159 +<p>See also <a href="qtservicebase.html#resume">resume</a>() and <a href="qtservicecontroller.html#pause">QtServiceController::pause</a>().</p>
  160 +<h3 class="fn"><a name="processCommand"></a>void QtServiceBase::processCommand ( int <i>code</i> )&nbsp;&nbsp;<tt> [virtual protected]</tt></h3>
  161 +<p>Reimplement this function to process the user command <i>code</i>.</p>
  162 +<p>This function is called in reply to controller requests. The default implementation does nothing.</p>
  163 +<p>See also <a href="qtservicecontroller.html#sendCommand">QtServiceController::sendCommand</a>().</p>
  164 +<h3 class="fn"><a name="resume"></a>void QtServiceBase::resume ()&nbsp;&nbsp;<tt> [virtual protected]</tt></h3>
  165 +<p>Reimplement this function to continue the service after a call to <a href="qtservicebase.html#pause">pause</a>().</p>
  166 +<p>This function is called in reply to controller requests. The default implementation does nothing.</p>
  167 +<p>See also <a href="qtservicebase.html#pause">pause</a>() and <a href="qtservicecontroller.html#resume">QtServiceController::resume</a>().</p>
  168 +<h3 class="fn"><a name="serviceDescription"></a><a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> QtServiceBase::serviceDescription () const</h3>
  169 +<p>Returns the description of the service.</p>
  170 +<p>See also <a href="qtservicebase.html#setServiceDescription">setServiceDescription</a>() and <a href="qtservicebase.html#serviceName">serviceName</a>().</p>
  171 +<h3 class="fn"><a name="serviceFlags"></a><a href="qtservicebase.html#ServiceFlag-enum">ServiceFlags</a> QtServiceBase::serviceFlags () const</h3>
  172 +<p>Returns the service's state which is decribed using the <a href="qtservicebase.html#ServiceFlag-enum">ServiceFlag</a> enum.</p>
  173 +<p>See also <a href="qtservicebase.html#ServiceFlag-enum">ServiceFlags</a> and <a href="qtservicebase.html#setServiceFlags">setServiceFlags</a>().</p>
  174 +<h3 class="fn"><a name="serviceName"></a><a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> QtServiceBase::serviceName () const</h3>
  175 +<p>Returns the name of the service.</p>
  176 +<p>See also <a href="qtservicebase.html#QtServiceBase">QtServiceBase</a>() and <a href="qtservicebase.html#serviceDescription">serviceDescription</a>().</p>
  177 +<h3 class="fn"><a name="setServiceDescription"></a>void QtServiceBase::setServiceDescription ( const <a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> &amp; <i>description</i> )</h3>
  178 +<p>Sets the description of the service to the given <i>description</i>.</p>
  179 +<p>See also <a href="qtservicebase.html#serviceDescription">serviceDescription</a>().</p>
  180 +<h3 class="fn"><a name="setServiceFlags"></a>void QtServiceBase::setServiceFlags ( <a href="qtservicebase.html#ServiceFlag-enum">ServiceFlags</a> <i>flags</i> )</h3>
  181 +<p>Sets the service's state to the state described by the given <i>flags</i>.</p>
  182 +<p>See also <a href="qtservicebase.html#ServiceFlag-enum">ServiceFlags</a> and <a href="qtservicebase.html#serviceFlags">serviceFlags</a>().</p>
  183 +<h3 class="fn"><a name="setStartupType"></a>void QtServiceBase::setStartupType ( <a href="qtservicecontroller.html#StartupType-enum">QtServiceController::StartupType</a> <i>type</i> )</h3>
  184 +<p>Sets the service's startup type to the given <i>type</i>.</p>
  185 +<p>See also <a href="qtservicecontroller.html#StartupType-enum">QtServiceController::StartupType</a> and <a href="qtservicebase.html#startupType">startupType</a>().</p>
  186 +<h3 class="fn"><a name="start"></a>void QtServiceBase::start ()&nbsp;&nbsp;<tt> [pure virtual protected]</tt></h3>
  187 +<p>This function must be implemented in <a href="qtservicebase.html">QtServiceBase</a> subclasses in order to perform the service's work. Usually you create some main object on the heap which is the heart of your service.</p>
  188 +<p>The function is only called when no service specific arguments were passed to the service constructor, and is called by <a href="qtservicebase.html#exec">exec</a>() after it has called the <a href="qtservicebase.html#executeApplication">executeApplication</a>() function.</p>
  189 +<p>Note that you <i>don't</i> need to create an application object or call its <a href="qtservicebase.html#exec">exec</a>() function explicitly.</p>
  190 +<p>See also <a href="qtservicebase.html#exec">exec</a>(), <a href="qtservicebase.html#stop">stop</a>(), and <a href="qtservicecontroller.html#start">QtServiceController::start</a>().</p>
  191 +<h3 class="fn"><a name="startupType"></a><a href="qtservicecontroller.html#StartupType-enum">QtServiceController::StartupType</a> QtServiceBase::startupType () const</h3>
  192 +<p>Returns the service's startup type.</p>
  193 +<p>See also <a href="qtservicecontroller.html#StartupType-enum">QtServiceController::StartupType</a> and <a href="qtservicebase.html#setStartupType">setStartupType</a>().</p>
  194 +<h3 class="fn"><a name="stop"></a>void QtServiceBase::stop ()&nbsp;&nbsp;<tt> [virtual protected]</tt></h3>
  195 +<p>Reimplement this function to perform additional cleanups before shutting down (for example deleting a main object if it was created in the <a href="qtservicebase.html#start">start</a>() function).</p>
  196 +<p>This function is called in reply to controller requests. The default implementation does nothing.</p>
  197 +<p>See also <a href="qtservicebase.html#start">start</a>() and <a href="qtservicecontroller.html#stop">QtServiceController::stop</a>().</p>
  198 +<p /><address><hr /><div align="center">
  199 +<table width="100%" cellspacing="0" border="0"><tr class="address">
  200 +<td width="30%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
  201 +<td width="40%" align="center"><a href="http://qt.nokia.com/doc/trademarks.html">Trademarks</a></td>
  202 +<td width="30%" align="right"><div align="right">Qt Solutions</div></td>
  203 +</tr></table></div></address></body>
  204 +</html>
... ...
src/qtservice/doc/html/qtservicecontroller-members.html 0 → 100644
... ... @@ -0,0 +1,46 @@
  1 +<?xml version="1.0" encoding="iso-8859-1"?>
  2 +<!DOCTYPE html
  3 + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 +<!-- qtservice.cpp -->
  6 +<head>
  7 + <title>List of All Members for QtServiceController</title>
  8 + <link href="classic.css" rel="stylesheet" type="text/css" />
  9 +</head>
  10 +<body>
  11 +<table border="0" cellpadding="0" cellspacing="0" width="100%">
  12 +<tr>
  13 +<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="57" height="67" border="0" /></td>
  14 +<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a></td>
  15 +</tr></table><h1 class="title">List of All Members for QtServiceController</h1>
  16 +<p>This is the complete list of members for <a href="qtservicecontroller.html">QtServiceController</a>, including inherited members.</p>
  17 +<p><table class="propsummary" width="100%" border="0" cellpadding="0" cellspacing="0">
  18 +<tr><td width="45%" valign="top"><ul>
  19 +<li><div class="fn">enum <b><a href="qtservicecontroller.html#StartupType-enum">StartupType</a></b></div></li>
  20 +<li><div class="fn"><b><a href="qtservicecontroller.html#QtServiceController">QtServiceController</a></b> ( const QString &amp; )</div></li>
  21 +<li><div class="fn"><b><a href="qtservicecontroller.html#dtor.QtServiceController">~QtServiceController</a></b> ()</div></li>
  22 +<li><div class="fn"><b><a href="qtservicecontroller.html#install">install</a></b> ( const QString &amp;, const QString &amp;, const QString &amp; ) : bool</div></li>
  23 +<li><div class="fn"><b><a href="qtservicecontroller.html#isInstalled">isInstalled</a></b> () const : bool</div></li>
  24 +<li><div class="fn"><b><a href="qtservicecontroller.html#isRunning">isRunning</a></b> () const : bool</div></li>
  25 +<li><div class="fn"><b><a href="qtservicecontroller.html#pause">pause</a></b> () : bool</div></li>
  26 +<li><div class="fn"><b><a href="qtservicecontroller.html#resume">resume</a></b> () : bool</div></li>
  27 +<li><div class="fn"><b><a href="qtservicecontroller.html#sendCommand">sendCommand</a></b> ( int ) : bool</div></li>
  28 +</ul></td><td valign="top"><ul>
  29 +<li><div class="fn"><b><a href="qtservicecontroller.html#serviceDescription">serviceDescription</a></b> () const : QString</div></li>
  30 +<li><div class="fn"><b><a href="qtservicecontroller.html#serviceFilePath">serviceFilePath</a></b> () const : QString</div></li>
  31 +<li><div class="fn"><b><a href="qtservicecontroller.html#serviceName">serviceName</a></b> () const : QString</div></li>
  32 +<li><div class="fn"><b><a href="qtservicecontroller.html#start">start</a></b> ( const QStringList &amp; ) : bool</div></li>
  33 +<li><div class="fn"><b><a href="qtservicecontroller.html#start-2">start</a></b> () : bool</div></li>
  34 +<li><div class="fn"><b><a href="qtservicecontroller.html#startupType">startupType</a></b> () const : StartupType</div></li>
  35 +<li><div class="fn"><b><a href="qtservicecontroller.html#stop">stop</a></b> () : bool</div></li>
  36 +<li><div class="fn"><b><a href="qtservicecontroller.html#uninstall">uninstall</a></b> () : bool</div></li>
  37 +</ul>
  38 +</td></tr>
  39 +</table></p>
  40 +<p /><address><hr /><div align="center">
  41 +<table width="100%" cellspacing="0" border="0"><tr class="address">
  42 +<td width="30%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
  43 +<td width="40%" align="center"><a href="http://qt.nokia.com/doc/trademarks.html">Trademarks</a></td>
  44 +<td width="30%" align="right"><div align="right">Qt Solutions</div></td>
  45 +</tr></table></div></address></body>
  46 +</html>
... ...
src/qtservice/doc/html/qtservicecontroller.html 0 → 100644
... ... @@ -0,0 +1,158 @@
  1 +<?xml version="1.0" encoding="iso-8859-1"?>
  2 +<!DOCTYPE html
  3 + PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
  4 +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  5 +<!-- qtservice.cpp -->
  6 +<head>
  7 + <title>QtServiceController Class Reference</title>
  8 + <link href="classic.css" rel="stylesheet" type="text/css" />
  9 +</head>
  10 +<body>
  11 +<table border="0" cellpadding="0" cellspacing="0" width="100%">
  12 +<tr>
  13 +<td align="left" valign="top" width="32"><img src="images/qt-logo.png" align="left" width="57" height="67" border="0" /></td>
  14 +<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"><a href="index.html"><font color="#004faf">Home</font></a></td>
  15 +</tr></table><h1 class="title">QtServiceController Class Reference</h1>
  16 +<p>The QtServiceController class allows you to control services from separate applications. <a href="#details">More...</a></p>
  17 +<pre> #include &lt;QtServiceController&gt;</pre><ul>
  18 +<li><a href="qtservicecontroller-members.html">List of all members, including inherited members</a></li>
  19 +</ul>
  20 +<hr />
  21 +<a name="public-types"></a>
  22 +<h2>Public Types</h2>
  23 +<table class="alignedsummary" border="0" cellpadding="0" cellspacing="0" width="100%">
  24 +<tr><td class="memItemLeft" align="right" valign="top">enum </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#StartupType-enum">StartupType</a></b> { AutoStartup, ManualStartup }</td></tr>
  25 +</table>
  26 +<hr />
  27 +<a name="public-functions"></a>
  28 +<h2>Public Functions</h2>
  29 +<table class="alignedsummary" border="0" cellpadding="0" cellspacing="0" width="100%">
  30 +<tr><td class="memItemLeft" align="right" valign="top"></td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#QtServiceController">QtServiceController</a></b> ( const QString &amp; <i>name</i> )</td></tr>
  31 +<tr><td class="memItemLeft" align="right" valign="top">virtual </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#dtor.QtServiceController">~QtServiceController</a></b> ()</td></tr>
  32 +<tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#isInstalled">isInstalled</a></b> () const</td></tr>
  33 +<tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#isRunning">isRunning</a></b> () const</td></tr>
  34 +<tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#pause">pause</a></b> ()</td></tr>
  35 +<tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#resume">resume</a></b> ()</td></tr>
  36 +<tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#sendCommand">sendCommand</a></b> ( int <i>code</i> )</td></tr>
  37 +<tr><td class="memItemLeft" align="right" valign="top">QString </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#serviceDescription">serviceDescription</a></b> () const</td></tr>
  38 +<tr><td class="memItemLeft" align="right" valign="top">QString </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#serviceFilePath">serviceFilePath</a></b> () const</td></tr>
  39 +<tr><td class="memItemLeft" align="right" valign="top">QString </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#serviceName">serviceName</a></b> () const</td></tr>
  40 +<tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#start">start</a></b> ( const QStringList &amp; <i>arguments</i> )</td></tr>
  41 +<tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#start-2">start</a></b> ()</td></tr>
  42 +<tr><td class="memItemLeft" align="right" valign="top">StartupType </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#startupType">startupType</a></b> () const</td></tr>
  43 +<tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#stop">stop</a></b> ()</td></tr>
  44 +<tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#uninstall">uninstall</a></b> ()</td></tr>
  45 +</table>
  46 +<hr />
  47 +<a name="static-public-members"></a>
  48 +<h2>Static Public Members</h2>
  49 +<table class="alignedsummary" border="0" cellpadding="0" cellspacing="0" width="100%">
  50 +<tr><td class="memItemLeft" align="right" valign="top">bool </td><td class="memItemRight" valign="bottom"><b><a href="qtservicecontroller.html#install">install</a></b> ( const QString &amp; <i>serviceFilePath</i>, const QString &amp; <i>account</i> = QString(), const QString &amp; <i>password</i> = QString() )</td></tr>
  51 +</table>
  52 +<a name="details"></a>
  53 +<hr />
  54 +<h2>Detailed Description</h2>
  55 +<p>The QtServiceController class allows you to control services from separate applications.</p>
  56 +<p>QtServiceController provides a collection of functions that lets you install and run a service controlling its execution, as well as query its status.</p>
  57 +<p>In order to run a service, the service must be installed in the system's service database using the <a href="qtservicecontroller.html#install">install</a>() function. The system will start the service depending on the specified <a href="qtservicecontroller.html#StartupType-enum">StartupType</a>; it can either be started during system startup, or when a process starts it manually.</p>
  58 +<p>Once a service is installed, the service can be run and controlled manually using the <a href="qtservicecontroller.html#start">start</a>(), <a href="qtservicecontroller.html#stop">stop</a>(), <a href="qtservicecontroller.html#pause">pause</a>(), <a href="qtservicecontroller.html#resume">resume</a>() or <a href="qtservicecontroller.html#sendCommand">sendCommand</a>() functions. You can at any time query for the service's status using the <a href="qtservicecontroller.html#isInstalled">isInstalled</a>() and <a href="qtservicecontroller.html#isRunning">isRunning</a>() functions, or you can query its properties using the <a href="qtservicecontroller.html#serviceDescription">serviceDescription</a>(), <a href="qtservicecontroller.html#serviceFilePath">serviceFilePath</a>(), <a href="qtservicecontroller.html#serviceName">serviceName</a>() and <a href="qtservicecontroller.html#startupType">startupType</a>() functions. For example:</p>
  59 +<pre> MyService service; \\ which inherits QtService
  60 + QString serviceFilePath;
  61 +
  62 + QtServiceController controller(service.serviceName());
  63 +
  64 + if (controller.install(serviceFilePath))
  65 + controller.start()
  66 +
  67 + if (controller.isRunning())
  68 + QMessageBox::information(this, tr(&quot;Service Status&quot;),
  69 + tr(&quot;The %1 service is started&quot;).arg(controller.serviceName()));
  70 +
  71 + ...
  72 +
  73 + controller.stop();
  74 + controller.uninstall();
  75 + }</pre>
  76 +<p>An instance of the service controller can only control one single service. To control several services within one application, you must create en equal number of service controllers.</p>
  77 +<p>The QtServiceController destructor neither stops nor uninstalls the associated service. To stop a service the <a href="qtservicecontroller.html#stop">stop</a>() function must be called explicitly. To uninstall a service, you can use the <a href="qtservicecontroller.html#uninstall">uninstall</a>() function.</p>
  78 +<p>See also <a href="qtservicebase.html">QtServiceBase</a> and <a href="qtservice.html">QtService</a>.</p>
  79 +<hr />
  80 +<h2>Member Type Documentation</h2>
  81 +<h3 class="fn"><a name="StartupType-enum"></a>enum QtServiceController::StartupType</h3>
  82 +<p>This enum describes when a service should be started.</p>
  83 +<p><table class="valuelist" border="1" cellpadding="2" cellspacing="1" width="100%">
  84 +<tr><th width="25%">Constant</th><th width="15%">Value</th><th width="60%">Description</th></tr>
  85 +<tr><td valign="top"><tt>QtServiceController::AutoStartup</tt></td><td align="center" valign="top"><tt>0</tt></td><td valign="top">The service is started during system startup.</td></tr>
  86 +<tr><td valign="top"><tt>QtServiceController::ManualStartup</tt></td><td align="center" valign="top"><tt>1</tt></td><td valign="top">The service must be started manually by a process.</td></tr>
  87 +</table></p>
  88 +<p><b>Warning:</b> The <i>StartupType</i> enum is ignored under UNIX-like systems. A service, or daemon, can only be started manually on such systems with current implementation.</p>
  89 +<p>See also <a href="qtservicecontroller.html#startupType">startupType</a>().</p>
  90 +<hr />
  91 +<h2>Member Function Documentation</h2>
  92 +<h3 class="fn"><a name="QtServiceController"></a>QtServiceController::QtServiceController ( const <a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> &amp; <i>name</i> )</h3>
  93 +<p>Creates a controller object for the service with the given <i>name</i>.</p>
  94 +<h3 class="fn"><a name="dtor.QtServiceController"></a>QtServiceController::~QtServiceController ()&nbsp;&nbsp;<tt> [virtual]</tt></h3>
  95 +<p>Destroys the service controller. This neither stops nor uninstalls the controlled service.</p>
  96 +<p>To stop a service the <a href="qtservicecontroller.html#stop">stop</a>() function must be called explicitly. To uninstall a service, you can use the <a href="qtservicecontroller.html#uninstall">uninstall</a>() function.</p>
  97 +<p>See also <a href="qtservicecontroller.html#stop">stop</a>() and <a href="qtservicecontroller.html#uninstall">QtServiceController::uninstall</a>().</p>
  98 +<h3 class="fn"><a name="install"></a>bool QtServiceController::install ( const <a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> &amp; <i>serviceFilePath</i>, const <a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> &amp; <i>account</i> = QString(), const <a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> &amp; <i>password</i> = QString() )&nbsp;&nbsp;<tt> [static]</tt></h3>
  99 +<p>Installs the service with the given <i>serviceFilePath</i> and returns true if the service is installed successfully; otherwise returns false.</p>
  100 +<p>On Windows service is installed in the system's service control manager with the given <i>account</i> and <i>password</i>.</p>
  101 +<p>On Unix service configuration is written to <a href="http://qt.nokia.com/doc/4.6/qsettings.html#Scope-enum">QSettings::SystemScope</a> using &quot;QtSoftware&quot; as organization name. <i>account</i> and <i>password</i> arguments are ignored.</p>
  102 +<p><b>Warning:</b> Due to the different implementations of how services (daemons) are installed on various UNIX-like systems, this method doesn't integrate the service into the system's startup scripts.</p>
  103 +<p>See also <a href="qtservicecontroller.html#uninstall">uninstall</a>() and <a href="qtservicecontroller.html#start">start</a>().</p>
  104 +<h3 class="fn"><a name="isInstalled"></a>bool QtServiceController::isInstalled () const</h3>
  105 +<p>Returns true if the service is installed; otherwise returns false.</p>
  106 +<p>On Windows it uses the system's service control manager.</p>
  107 +<p>On Unix it checks configuration written to <a href="http://qt.nokia.com/doc/4.6/qsettings.html#Scope-enum">QSettings::SystemScope</a> using &quot;QtSoftware&quot; as organization name.</p>
  108 +<p>See also <a href="qtservicecontroller.html#install">install</a>().</p>
  109 +<h3 class="fn"><a name="isRunning"></a>bool QtServiceController::isRunning () const</h3>
  110 +<p>Returns true if the service is running; otherwise returns false. A service must be installed before it can be run using a controller.</p>
  111 +<p>See also <a href="qtservicecontroller.html#start">start</a>() and <a href="qtservicecontroller.html#isInstalled">isInstalled</a>().</p>
  112 +<h3 class="fn"><a name="pause"></a>bool QtServiceController::pause ()</h3>
  113 +<p>Requests the running service to pause. If the service's state is <a href="qtservicebase.html#ServiceFlag-enum">QtServiceBase::CanBeSuspended</a>, the service will call the <a href="qtservicebase.html#pause">QtServiceBase::pause</a>() implementation. The function does nothing if the service is not running.</p>
  114 +<p>Returns true if a running service was successfully paused; otherwise returns false.</p>
  115 +<p>See also <a href="qtservicecontroller.html#resume">resume</a>(), <a href="qtservicebase.html#pause">QtServiceBase::pause</a>(), and <a href="qtservicebase.html#ServiceFlag-enum">QtServiceBase::ServiceFlags</a>.</p>
  116 +<h3 class="fn"><a name="resume"></a>bool QtServiceController::resume ()</h3>
  117 +<p>Requests the running service to continue. If the service's state is <a href="qtservicebase.html#ServiceFlag-enum">QtServiceBase::CanBeSuspended</a>, the service will call the <a href="qtservicebase.html#resume">QtServiceBase::resume</a>() implementation. This function does nothing if the service is not running.</p>
  118 +<p>Returns true if a running service was successfully resumed; otherwise returns false.</p>
  119 +<p>See also <a href="qtservicecontroller.html#pause">pause</a>(), <a href="qtservicebase.html#resume">QtServiceBase::resume</a>(), and <a href="qtservicebase.html#ServiceFlag-enum">QtServiceBase::ServiceFlags</a>.</p>
  120 +<h3 class="fn"><a name="sendCommand"></a>bool QtServiceController::sendCommand ( int <i>code</i> )</h3>
  121 +<p>Sends the user command <i>code</i> to the service. The service will call the <a href="qtservicebase.html#processCommand">QtServiceBase::processCommand</a>() implementation. This function does nothing if the service is not running.</p>
  122 +<p>Returns true if the request was sent to a running service; otherwise returns false.</p>
  123 +<p>See also <a href="qtservicebase.html#processCommand">QtServiceBase::processCommand</a>().</p>
  124 +<h3 class="fn"><a name="serviceDescription"></a><a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> QtServiceController::serviceDescription () const</h3>
  125 +<p>Returns the description of the controlled service.</p>
  126 +<p>See also <a href="qtservicecontroller.html#install">install</a>() and <a href="qtservicecontroller.html#serviceName">serviceName</a>().</p>
  127 +<h3 class="fn"><a name="serviceFilePath"></a><a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> QtServiceController::serviceFilePath () const</h3>
  128 +<p>Returns the file path to the controlled service.</p>
  129 +<p>See also <a href="qtservicecontroller.html#install">install</a>() and <a href="qtservicecontroller.html#serviceName">serviceName</a>().</p>
  130 +<h3 class="fn"><a name="serviceName"></a><a href="http://qt.nokia.com/doc/4.6/qstring.html">QString</a> QtServiceController::serviceName () const</h3>
  131 +<p>Returns the name of the controlled service.</p>
  132 +<p>See also <a href="qtservicecontroller.html#QtServiceController">QtServiceController</a>() and <a href="qtservicecontroller.html#serviceDescription">serviceDescription</a>().</p>
  133 +<h3 class="fn"><a name="start"></a>bool QtServiceController::start ( const <a href="http://qt.nokia.com/doc/4.6/qstringlist.html">QStringList</a> &amp; <i>arguments</i> )</h3>
  134 +<p>Starts the installed service passing the given <i>arguments</i> to the service. A service must be installed before a controller can run it.</p>
  135 +<p>Returns true if the service could be started; otherwise returns false.</p>
  136 +<p>See also <a href="qtservicecontroller.html#install">install</a>() and <a href="qtservicecontroller.html#stop">stop</a>().</p>
  137 +<h3 class="fn"><a name="start-2"></a>bool QtServiceController::start ()</h3>
  138 +<p>This is an overloaded function.</p>
  139 +<p>Starts the installed service without passing any arguments to the service.</p>
  140 +<h3 class="fn"><a name="startupType"></a><a href="qtservicecontroller.html#StartupType-enum">StartupType</a> QtServiceController::startupType () const</h3>
  141 +<p>Returns the startup type of the controlled service.</p>
  142 +<p>See also <a href="qtservicecontroller.html#install">install</a>() and <a href="qtservicecontroller.html#serviceName">serviceName</a>().</p>
  143 +<h3 class="fn"><a name="stop"></a>bool QtServiceController::stop ()</h3>
  144 +<p>Requests the running service to stop. The service will call the <a href="qtservicebase.html#stop">QtServiceBase::stop</a>() implementation unless the service's state is <a href="qtservicebase.html#ServiceFlag-enum">QtServiceBase::CannotBeStopped</a>. This function does nothing if the service is not running.</p>
  145 +<p>Returns true if a running service was successfully stopped; otherwise false.</p>
  146 +<p>See also <a href="qtservicecontroller.html#start">start</a>(), <a href="qtservicebase.html#stop">QtServiceBase::stop</a>(), and <a href="qtservicebase.html#ServiceFlag-enum">QtServiceBase::ServiceFlags</a>.</p>
  147 +<h3 class="fn"><a name="uninstall"></a>bool QtServiceController::uninstall ()</h3>
  148 +<p>Uninstalls the service and returns true if successful; otherwise returns false.</p>
  149 +<p>On Windows service is uninstalled using the system's service control manager.</p>
  150 +<p>On Unix service configuration is cleared using <a href="http://qt.nokia.com/doc/4.6/qsettings.html#Scope-enum">QSettings::SystemScope</a> with &quot;QtSoftware&quot; as organization name.</p>
  151 +<p>See also <a href="qtservicecontroller.html#install">install</a>().</p>
  152 +<p /><address><hr /><div align="center">
  153 +<table width="100%" cellspacing="0" border="0"><tr class="address">
  154 +<td width="30%" align="left">Copyright &copy; 2010 Nokia Corporation and/or its subsidiary(-ies)</td>
  155 +<td width="40%" align="center"><a href="http://qt.nokia.com/doc/trademarks.html">Trademarks</a></td>
  156 +<td width="30%" align="right"><div align="right">Qt Solutions</div></td>
  157 +</tr></table></div></address></body>
  158 +</html>
... ...
src/qtservice/doc/images/qt-logo.png 0 → 100644

3.98 KB

src/qtservice/doc/index.qdoc 0 → 100644
... ... @@ -0,0 +1,86 @@
  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 +*/
... ...
src/qtservice/src/QtServiceBase 0 → 100644
... ... @@ -0,0 +1 @@
  1 +#include "qtservice.h"
... ...
src/qtservice/src/QtServiceController 0 → 100644
... ... @@ -0,0 +1 @@
  1 +#include "qtservice.h"
... ...
src/qtservice/src/qtservice.cpp 0 → 100644
... ... @@ -0,0 +1,1112 @@
  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 "qtservice.h"
  42 +#include "qtservice_p.h"
  43 +#include <QCoreApplication>
  44 +#include <stdio.h>
  45 +#include <QTimer>
  46 +#include <QVector>
  47 +#include <QProcess>
  48 +
  49 +#if defined(QTSERVICE_DEBUG)
  50 +#include <QDebug>
  51 +#include <QFile>
  52 +#include <QTime>
  53 +#include <QMutex>
  54 +#if defined(Q_OS_WIN32)
  55 +#include <qt_windows.h>
  56 +#else
  57 +#include <unistd.h>
  58 +#include <stdlib.h>
  59 +#endif
  60 +
  61 +static QFile* f = 0;
  62 +
  63 +static void qtServiceCloseDebugLog()
  64 +{
  65 + if (!f)
  66 + return;
  67 + QString ps(QTime::currentTime().toString("HH:mm:ss.zzz ") + QLatin1String("--- DEBUG LOG CLOSED ---\n\n"));
  68 + f->write(ps.toAscii());
  69 + f->flush();
  70 + f->close();
  71 + delete f;
  72 + f = 0;
  73 +}
  74 +
  75 +void qtServiceLogDebug(QtMsgType type, const char* msg)
  76 +{
  77 + static QMutex mutex;
  78 + QMutexLocker locker(&mutex);
  79 + QString s(QTime::currentTime().toString("HH:mm:ss.zzz "));
  80 + s += QString("[%1] ").arg(
  81 +#if defined(Q_OS_WIN32)
  82 + GetCurrentProcessId());
  83 +#else
  84 + getpid());
  85 +#endif
  86 +
  87 + if (!f) {
  88 +#if defined(Q_OS_WIN32)
  89 + f = new QFile("c:/service-debuglog.txt");
  90 +#else
  91 + f = new QFile("/tmp/service-debuglog.txt");
  92 +#endif
  93 + if (!f->open(QIODevice::WriteOnly | QIODevice::Append)) {
  94 + delete f;
  95 + f = 0;
  96 + return;
  97 + }
  98 + QString ps(QLatin1String("\n") + s + QLatin1String("--- DEBUG LOG OPENED ---\n"));
  99 + f->write(ps.toAscii());
  100 + }
  101 +
  102 + switch (type) {
  103 + case QtWarningMsg:
  104 + s += QLatin1String("WARNING: ");
  105 + break;
  106 + case QtCriticalMsg:
  107 + s += QLatin1String("CRITICAL: ");
  108 + break;
  109 + case QtFatalMsg:
  110 + s+= QLatin1String("FATAL: ");
  111 + break;
  112 + case QtDebugMsg:
  113 + s += QLatin1String("DEBUG: ");
  114 + break;
  115 + default:
  116 + // Nothing
  117 + break;
  118 + }
  119 +
  120 + s += msg;
  121 + s += QLatin1String("\n");
  122 +
  123 + f->write(s.toAscii());
  124 + f->flush();
  125 +
  126 + if (type == QtFatalMsg) {
  127 + qtServiceCloseDebugLog();
  128 + exit(1);
  129 + }
  130 +}
  131 +
  132 +#endif
  133 +
  134 +/*!
  135 + \class QtServiceController
  136 +
  137 + \brief The QtServiceController class allows you to control
  138 + services from separate applications.
  139 +
  140 + QtServiceController provides a collection of functions that lets
  141 + you install and run a service controlling its execution, as well
  142 + as query its status.
  143 +
  144 + In order to run a service, the service must be installed in the
  145 + system's service database using the install() function. The system
  146 + will start the service depending on the specified StartupType; it
  147 + can either be started during system startup, or when a process
  148 + starts it manually.
  149 +
  150 + Once a service is installed, the service can be run and controlled
  151 + manually using the start(), stop(), pause(), resume() or
  152 + sendCommand() functions. You can at any time query for the
  153 + service's status using the isInstalled() and isRunning()
  154 + functions, or you can query its properties using the
  155 + serviceDescription(), serviceFilePath(), serviceName() and
  156 + startupType() functions. For example:
  157 +
  158 + \code
  159 + MyService service; \\ which inherits QtService
  160 + QString serviceFilePath;
  161 +
  162 + QtServiceController controller(service.serviceName());
  163 +
  164 + if (controller.install(serviceFilePath))
  165 + controller.start()
  166 +
  167 + if (controller.isRunning())
  168 + QMessageBox::information(this, tr("Service Status"),
  169 + tr("The %1 service is started").arg(controller.serviceName()));
  170 +
  171 + ...
  172 +
  173 + controller.stop();
  174 + controller.uninstall();
  175 + }
  176 + \endcode
  177 +
  178 + An instance of the service controller can only control one single
  179 + service. To control several services within one application, you
  180 + must create en equal number of service controllers.
  181 +
  182 + The QtServiceController destructor neither stops nor uninstalls
  183 + the associated service. To stop a service the stop() function must
  184 + be called explicitly. To uninstall a service, you can use the
  185 + uninstall() function.
  186 +
  187 + \sa QtServiceBase, QtService
  188 +*/
  189 +
  190 +/*!
  191 + \enum QtServiceController::StartupType
  192 + This enum describes when a service should be started.
  193 +
  194 + \value AutoStartup The service is started during system startup.
  195 + \value ManualStartup The service must be started manually by a process.
  196 +
  197 + \warning The \a StartupType enum is ignored under UNIX-like
  198 + systems. A service, or daemon, can only be started manually on such
  199 + systems with current implementation.
  200 +
  201 + \sa startupType()
  202 +*/
  203 +
  204 +
  205 +/*!
  206 + Creates a controller object for the service with the given
  207 + \a name.
  208 +*/
  209 +QtServiceController::QtServiceController(const QString &name)
  210 + : d_ptr(new QtServiceControllerPrivate())
  211 +{
  212 + Q_D(QtServiceController);
  213 + d->q_ptr = this;
  214 + d->serviceName = name;
  215 +}
  216 +/*!
  217 + Destroys the service controller. This neither stops nor uninstalls
  218 + the controlled service.
  219 +
  220 + To stop a service the stop() function must be called
  221 + explicitly. To uninstall a service, you can use the uninstall()
  222 + function.
  223 +
  224 + \sa stop(), QtServiceController::uninstall()
  225 +*/
  226 +QtServiceController::~QtServiceController()
  227 +{
  228 + delete d_ptr;
  229 +}
  230 +/*!
  231 + \fn bool QtServiceController::isInstalled() const
  232 +
  233 + Returns true if the service is installed; otherwise returns false.
  234 +
  235 + On Windows it uses the system's service control manager.
  236 +
  237 + On Unix it checks configuration written to QSettings::SystemScope
  238 + using "QtSoftware" as organization name.
  239 +
  240 + \sa install()
  241 +*/
  242 +
  243 +/*!
  244 + \fn bool QtServiceController::isRunning() const
  245 +
  246 + Returns true if the service is running; otherwise returns false. A
  247 + service must be installed before it can be run using a controller.
  248 +
  249 + \sa start(), isInstalled()
  250 +*/
  251 +
  252 +/*!
  253 + Returns the name of the controlled service.
  254 +
  255 + \sa QtServiceController(), serviceDescription()
  256 +*/
  257 +QString QtServiceController::serviceName() const
  258 +{
  259 + Q_D(const QtServiceController);
  260 + return d->serviceName;
  261 +}
  262 +/*!
  263 + \fn QString QtServiceController::serviceDescription() const
  264 +
  265 + Returns the description of the controlled service.
  266 +
  267 + \sa install(), serviceName()
  268 +*/
  269 +
  270 +/*!
  271 + \fn QtServiceController::StartupType QtServiceController::startupType() const
  272 +
  273 + Returns the startup type of the controlled service.
  274 +
  275 + \sa install(), serviceName()
  276 +*/
  277 +
  278 +/*!
  279 + \fn QString QtServiceController::serviceFilePath() const
  280 +
  281 + Returns the file path to the controlled service.
  282 +
  283 + \sa install(), serviceName()
  284 +*/
  285 +
  286 +/*!
  287 + Installs the service with the given \a serviceFilePath
  288 + and returns true if the service is installed
  289 + successfully; otherwise returns false.
  290 +
  291 + On Windows service is installed in the system's service control manager with the given
  292 + \a account and \a password.
  293 +
  294 + On Unix service configuration is written to QSettings::SystemScope
  295 + using "QtSoftware" as organization name. \a account and \a password
  296 + arguments are ignored.
  297 +
  298 + \warning Due to the different implementations of how services (daemons)
  299 + are installed on various UNIX-like systems, this method doesn't
  300 + integrate the service into the system's startup scripts.
  301 +
  302 + \sa uninstall(), start()
  303 +*/
  304 +bool QtServiceController::install(const QString &serviceFilePath, const QString &account,
  305 + const QString &password)
  306 +{
  307 + QStringList arguments;
  308 + arguments << QLatin1String("-i");
  309 + arguments << account;
  310 + arguments << password;
  311 + return (QProcess::execute(serviceFilePath, arguments) == 0);
  312 +}
  313 +
  314 +
  315 +/*!
  316 + \fn bool QtServiceController::uninstall()
  317 +
  318 + Uninstalls the service and returns true if successful; otherwise returns false.
  319 +
  320 + On Windows service is uninstalled using the system's service control manager.
  321 +
  322 + On Unix service configuration is cleared using QSettings::SystemScope
  323 + with "QtSoftware" as organization name.
  324 +
  325 +
  326 + \sa install()
  327 +*/
  328 +
  329 +/*!
  330 + \fn bool QtServiceController::start(const QStringList &arguments)
  331 +
  332 + Starts the installed service passing the given \a arguments to the
  333 + service. A service must be installed before a controller can run it.
  334 +
  335 + Returns true if the service could be started; otherwise returns
  336 + false.
  337 +
  338 + \sa install(), stop()
  339 +*/
  340 +
  341 +/*!
  342 + \overload
  343 +
  344 + Starts the installed service without passing any arguments to the service.
  345 +*/
  346 +bool QtServiceController::start()
  347 +{
  348 + return start(QStringList());
  349 +}
  350 +
  351 +/*!
  352 + \fn bool QtServiceController::stop()
  353 +
  354 + Requests the running service to stop. The service will call the
  355 + QtServiceBase::stop() implementation unless the service's state
  356 + is QtServiceBase::CannotBeStopped. This function does nothing if
  357 + the service is not running.
  358 +
  359 + Returns true if a running service was successfully stopped;
  360 + otherwise false.
  361 +
  362 + \sa start(), QtServiceBase::stop(), QtServiceBase::ServiceFlags
  363 +*/
  364 +
  365 +/*!
  366 + \fn bool QtServiceController::pause()
  367 +
  368 + Requests the running service to pause. If the service's state is
  369 + QtServiceBase::CanBeSuspended, the service will call the
  370 + QtServiceBase::pause() implementation. The function does nothing
  371 + if the service is not running.
  372 +
  373 + Returns true if a running service was successfully paused;
  374 + otherwise returns false.
  375 +
  376 + \sa resume(), QtServiceBase::pause(), QtServiceBase::ServiceFlags
  377 +*/
  378 +
  379 +/*!
  380 + \fn bool QtServiceController::resume()
  381 +
  382 + Requests the running service to continue. If the service's state
  383 + is QtServiceBase::CanBeSuspended, the service will call the
  384 + QtServiceBase::resume() implementation. This function does nothing
  385 + if the service is not running.
  386 +
  387 + Returns true if a running service was successfully resumed;
  388 + otherwise returns false.
  389 +
  390 + \sa pause(), QtServiceBase::resume(), QtServiceBase::ServiceFlags
  391 +*/
  392 +
  393 +/*!
  394 + \fn bool QtServiceController::sendCommand(int code)
  395 +
  396 + Sends the user command \a code to the service. The service will
  397 + call the QtServiceBase::processCommand() implementation. This
  398 + function does nothing if the service is not running.
  399 +
  400 + Returns true if the request was sent to a running service;
  401 + otherwise returns false.
  402 +
  403 + \sa QtServiceBase::processCommand()
  404 +*/
  405 +
  406 +class QtServiceStarter : public QObject
  407 +{
  408 + Q_OBJECT
  409 +public:
  410 + QtServiceStarter(QtServiceBasePrivate *service)
  411 + : QObject(), d_ptr(service) {}
  412 +public slots:
  413 + void slotStart()
  414 + {
  415 + d_ptr->startService();
  416 + }
  417 +private:
  418 + QtServiceBasePrivate *d_ptr;
  419 +};
  420 +#include "qtservice.moc"
  421 +
  422 +QtServiceBase *QtServiceBasePrivate::instance = 0;
  423 +
  424 +QtServiceBasePrivate::QtServiceBasePrivate(const QString &name)
  425 + : startupType(QtServiceController::ManualStartup), serviceFlags(0), controller(name)
  426 +{
  427 +
  428 +}
  429 +
  430 +QtServiceBasePrivate::~QtServiceBasePrivate()
  431 +{
  432 +
  433 +}
  434 +
  435 +void QtServiceBasePrivate::startService()
  436 +{
  437 + q_ptr->start();
  438 +}
  439 +
  440 +int QtServiceBasePrivate::run(bool asService, const QStringList &argList)
  441 +{
  442 + int argc = argList.size();
  443 + QVector<char *> argv(argc);
  444 + QList<QByteArray> argvData;
  445 + for (int i = 0; i < argc; ++i)
  446 + argvData.append(argList.at(i).toLocal8Bit());
  447 + for (int i = 0; i < argc; ++i)
  448 + argv[i] = argvData[i].data();
  449 +
  450 + if (asService && !sysInit())
  451 + return -1;
  452 +
  453 + q_ptr->createApplication(argc, argv.data());
  454 + QCoreApplication *app = QCoreApplication::instance();
  455 + if (!app)
  456 + return -1;
  457 +
  458 + if (asService)
  459 + sysSetPath();
  460 +
  461 + QtServiceStarter starter(this);
  462 + QTimer::singleShot(0, &starter, SLOT(slotStart()));
  463 + int res = q_ptr->executeApplication();
  464 + delete app;
  465 +
  466 + if (asService)
  467 + sysCleanup();
  468 + return res;
  469 +}
  470 +
  471 +
  472 +/*!
  473 + \class QtServiceBase
  474 +
  475 + \brief The QtServiceBase class provides an API for implementing
  476 + Windows services and Unix daemons.
  477 +
  478 + A Windows service or Unix daemon (a "service"), is a program that
  479 + runs "in the background" independently of whether a user is logged
  480 + in or not. A service is often set up to start when the machine
  481 + boots up, and will typically run continuously as long as the
  482 + machine is on.
  483 +
  484 + Services are usually non-interactive console applications. User
  485 + interaction, if required, is usually implemented in a separate,
  486 + normal GUI application that communicates with the service through
  487 + an IPC channel. For simple communication,
  488 + QtServiceController::sendCommand() and QtService::processCommand()
  489 + may be used, possibly in combination with a shared settings
  490 + file. For more complex, interactive communication, a custom IPC
  491 + channel should be used, e.g. based on Qt's networking classes. (In
  492 + certain circumstances, a service may provide a GUI itself,
  493 + ref. the "interactive" example documentation).
  494 +
  495 + Typically, you will create a service by subclassing the QtService
  496 + template class which inherits QtServiceBase and allows you to
  497 + create a service for a particular application type.
  498 +
  499 + The Windows implementation uses the NT Service Control Manager,
  500 + and the application can be controlled through the system
  501 + administration tools. Services are usually launched using the
  502 + system account, which requires that all DLLs that the service
  503 + executable depends on (i.e. Qt), are located in the same directory
  504 + as the service, or in a system path.
  505 +
  506 + On Unix a service is implemented as a daemon.
  507 +
  508 + You can retrieve the service's description, state, and startup
  509 + type using the serviceDescription(), serviceFlags() and
  510 + startupType() functions respectively. The service's state is
  511 + decribed by the ServiceFlag enum. The mentioned properites can
  512 + also be set using the corresponding set functions. In addition you
  513 + can retrieve the service's name using the serviceName() function.
  514 +
  515 + Several of QtServiceBase's protected functions are called on
  516 + requests from the QtServiceController class:
  517 +
  518 + \list
  519 + \o start()
  520 + \o pause()
  521 + \o processCommand()
  522 + \o resume()
  523 + \o stop()
  524 + \endlist
  525 +
  526 + You can control any given service using an instance of the
  527 + QtServiceController class which also allows you to control
  528 + services from separate applications. The mentioned functions are
  529 + all virtual and won't do anything unless they are
  530 + reimplemented. You can reimplement these functions to pause and
  531 + resume the service's execution, as well as process user commands
  532 + and perform additional clean-ups before shutting down.
  533 +
  534 + QtServiceBase also provides the static instance() function which
  535 + returns a pointer to an application's QtServiceBase instance. In
  536 + addition, a service can report events to the system's event log
  537 + using the logMessage() function. The MessageType enum describes
  538 + the different types of messages a service reports.
  539 +
  540 + The implementation of a service application's main function
  541 + typically creates an service object derived by subclassing the
  542 + QtService template class. Then the main function will call this
  543 + service's exec() function, and return the result of that call. For
  544 + example:
  545 +
  546 + \code
  547 + int main(int argc, char **argv)
  548 + {
  549 + MyService service(argc, argv);
  550 + return service.exec();
  551 + }
  552 + \endcode
  553 +
  554 + When the exec() function is called, it will parse the service
  555 + specific arguments passed in \c argv, perform the required
  556 + actions, and return.
  557 +
  558 + \target serviceSpecificArguments
  559 +
  560 + The following arguments are recognized as service specific:
  561 +
  562 + \table
  563 + \header \i Short \i Long \i Explanation
  564 + \row \i -i \i -install \i Install the service.
  565 + \row \i -u \i -uninstall \i Uninstall the service.
  566 + \row \i -e \i -exec
  567 + \i Execute the service as a standalone application (useful for debug purposes).
  568 + This is a blocking call, the service will be executed like a normal application.
  569 + In this mode you will not be able to communicate with the service from the contoller.
  570 + \row \i -t \i -terminate \i Stop the service.
  571 + \row \i -p \i -pause \i Pause the service.
  572 + \row \i -r \i -resume \i Resume a paused service.
  573 + \row \i -c \e{cmd} \i -command \e{cmd}
  574 + \i Send the user defined command code \e{cmd} to the service application.
  575 + \row \i -v \i -version \i Display version and status information.
  576 + \endtable
  577 +
  578 + If \e none of the arguments is recognized as service specific,
  579 + exec() will first call the createApplication() function, then
  580 + executeApplication() and finally the start() function. In the end,
  581 + exec() returns while the service continues in its own process
  582 + waiting for commands from the service controller.
  583 +
  584 + \sa QtService, QtServiceController
  585 +*/
  586 +
  587 +/*!
  588 + \enum QtServiceBase::MessageType
  589 +
  590 + This enum describes the different types of messages a service
  591 + reports to the system log.
  592 +
  593 + \value Success An operation has succeeded, e.g. the service
  594 + is started.
  595 + \value Error An operation failed, e.g. the service failed to start.
  596 + \value Warning An operation caused a warning that might require user
  597 + interaction.
  598 + \value Information Any type of usually non-critical information.
  599 +*/
  600 +
  601 +/*!
  602 + \enum QtServiceBase::ServiceFlag
  603 +
  604 + This enum describes the different capabilities of a service.
  605 +
  606 + \value Default The service can be stopped, but not suspended.
  607 + \value CanBeSuspended The service can be suspended.
  608 + \value CannotBeStopped The service cannot be stopped.
  609 + \value NeedsStopOnShutdown (Windows only) The service will be stopped before the system shuts down. Note that Microsoft recommends this only for services that must absolutely clean up during shutdown, because there is a limited time available for shutdown of services.
  610 +*/
  611 +
  612 +/*!
  613 + Creates a service instance called \a name. The \a argc and \a argv
  614 + parameters are parsed after the exec() function has been
  615 + called. Then they are passed to the application's constructor.
  616 + The application type is determined by the QtService subclass.
  617 +
  618 + The service is neither installed nor started. The name must not
  619 + contain any backslashes or be longer than 255 characters. In
  620 + addition, the name must be unique in the system's service
  621 + database.
  622 +
  623 + \sa exec(), start(), QtServiceController::install()
  624 +*/
  625 +QtServiceBase::QtServiceBase(int argc, char **argv, const QString &name)
  626 +{
  627 +#if defined(QTSERVICE_DEBUG)
  628 + qInstallMsgHandler(qtServiceLogDebug);
  629 + qAddPostRoutine(qtServiceCloseDebugLog);
  630 +#endif
  631 +
  632 + Q_ASSERT(!QtServiceBasePrivate::instance);
  633 + QtServiceBasePrivate::instance = this;
  634 +
  635 + QString nm(name);
  636 + if (nm.length() > 255) {
  637 + qWarning("QtService: 'name' is longer than 255 characters.");
  638 + nm.truncate(255);
  639 + }
  640 + if (nm.contains('\\')) {
  641 + qWarning("QtService: 'name' contains backslashes '\\'.");
  642 + nm.replace((QChar)'\\', (QChar)'\0');
  643 + }
  644 +
  645 + d_ptr = new QtServiceBasePrivate(nm);
  646 + d_ptr->q_ptr = this;
  647 +
  648 + d_ptr->serviceFlags = 0;
  649 + d_ptr->sysd = 0;
  650 + for (int i = 0; i < argc; ++i)
  651 + d_ptr->args.append(QString::fromLocal8Bit(argv[i]));
  652 +}
  653 +
  654 +/*!
  655 + Destroys the service object. This neither stops nor uninstalls the
  656 + service.
  657 +
  658 + To stop a service the stop() function must be called
  659 + explicitly. To uninstall a service, you can use the
  660 + QtServiceController::uninstall() function.
  661 +
  662 + \sa stop(), QtServiceController::uninstall()
  663 +*/
  664 +QtServiceBase::~QtServiceBase()
  665 +{
  666 + delete d_ptr;
  667 + QtServiceBasePrivate::instance = 0;
  668 +}
  669 +
  670 +/*!
  671 + Returns the name of the service.
  672 +
  673 + \sa QtServiceBase(), serviceDescription()
  674 +*/
  675 +QString QtServiceBase::serviceName() const
  676 +{
  677 + return d_ptr->controller.serviceName();
  678 +}
  679 +
  680 +/*!
  681 + Returns the description of the service.
  682 +
  683 + \sa setServiceDescription(), serviceName()
  684 +*/
  685 +QString QtServiceBase::serviceDescription() const
  686 +{
  687 + return d_ptr->serviceDescription;
  688 +}
  689 +
  690 +/*!
  691 + Sets the description of the service to the given \a description.
  692 +
  693 + \sa serviceDescription()
  694 +*/
  695 +void QtServiceBase::setServiceDescription(const QString &description)
  696 +{
  697 + d_ptr->serviceDescription = description;
  698 +}
  699 +
  700 +/*!
  701 + Returns the service's startup type.
  702 +
  703 + \sa QtServiceController::StartupType, setStartupType()
  704 +*/
  705 +QtServiceController::StartupType QtServiceBase::startupType() const
  706 +{
  707 + return d_ptr->startupType;
  708 +}
  709 +
  710 +/*!
  711 + Sets the service's startup type to the given \a type.
  712 +
  713 + \sa QtServiceController::StartupType, startupType()
  714 +*/
  715 +void QtServiceBase::setStartupType(QtServiceController::StartupType type)
  716 +{
  717 + d_ptr->startupType = type;
  718 +}
  719 +
  720 +/*!
  721 + Returns the service's state which is decribed using the
  722 + ServiceFlag enum.
  723 +
  724 + \sa ServiceFlags, setServiceFlags()
  725 +*/
  726 +QtServiceBase::ServiceFlags QtServiceBase::serviceFlags() const
  727 +{
  728 + return d_ptr->serviceFlags;
  729 +}
  730 +
  731 +/*!
  732 + \fn void QtServiceBase::setServiceFlags(ServiceFlags flags)
  733 +
  734 + Sets the service's state to the state described by the given \a
  735 + flags.
  736 +
  737 + \sa ServiceFlags, serviceFlags()
  738 +*/
  739 +
  740 +/*!
  741 + Executes the service.
  742 +
  743 + When the exec() function is called, it will parse the \l
  744 + {serviceSpecificArguments} {service specific arguments} passed in
  745 + \c argv, perform the required actions, and exit.
  746 +
  747 + If none of the arguments is recognized as service specific, exec()
  748 + will first call the createApplication() function, then executeApplication() and
  749 + finally the start() function. In the end, exec()
  750 + returns while the service continues in its own process waiting for
  751 + commands from the service controller.
  752 +
  753 + \sa QtServiceController
  754 +*/
  755 +int QtServiceBase::exec()
  756 +{
  757 + if (d_ptr->args.size() > 1) {
  758 + QString a = d_ptr->args.at(1);
  759 + if (a == QLatin1String("-i") || a == QLatin1String("-install")) {
  760 + if (!d_ptr->controller.isInstalled()) {
  761 + QString account;
  762 + QString password;
  763 + if (d_ptr->args.size() > 2)
  764 + account = d_ptr->args.at(2);
  765 + if (d_ptr->args.size() > 3)
  766 + password = d_ptr->args.at(3);
  767 + if (!d_ptr->install(account, password)) {
  768 + fprintf(stderr, "The service %s could not be installed\n", serviceName().toLatin1().constData());
  769 + return -1;
  770 + } else {
  771 + printf("The service %s has been installed under: %s\n",
  772 + serviceName().toLatin1().constData(), d_ptr->filePath().toLatin1().constData());
  773 + }
  774 + } else {
  775 + fprintf(stderr, "The service %s is already installed\n", serviceName().toLatin1().constData());
  776 + }
  777 + return 0;
  778 + } else if (a == QLatin1String("-u") || a == QLatin1String("-uninstall")) {
  779 + if (d_ptr->controller.isInstalled()) {
  780 + if (!d_ptr->controller.uninstall()) {
  781 + fprintf(stderr, "The service %s could not be uninstalled\n", serviceName().toLatin1().constData());
  782 + return -1;
  783 + } else {
  784 + printf("The service %s has been uninstalled.\n",
  785 + serviceName().toLatin1().constData());
  786 + }
  787 + } else {
  788 + fprintf(stderr, "The service %s is not installed\n", serviceName().toLatin1().constData());
  789 + }
  790 + return 0;
  791 + } else if (a == QLatin1String("-v") || a == QLatin1String("-version")) {
  792 + printf("The service\n"
  793 + "\t%s\n\t%s\n\n", serviceName().toLatin1().constData(), d_ptr->args.at(0).toLatin1().constData());
  794 + printf("is %s", (d_ptr->controller.isInstalled() ? "installed" : "not installed"));
  795 + printf(" and %s\n\n", (d_ptr->controller.isRunning() ? "running" : "not running"));
  796 + return 0;
  797 + } else if (a == QLatin1String("-e") || a == QLatin1String("-exec")) {
  798 + d_ptr->args.removeAt(1);
  799 + int ec = d_ptr->run(false, d_ptr->args);
  800 + if (ec == -1)
  801 + qErrnoWarning("The service could not be executed.");
  802 + return ec;
  803 + } else if (a == QLatin1String("-t") || a == QLatin1String("-terminate")) {
  804 + if (!d_ptr->controller.stop())
  805 + qErrnoWarning("The service could not be stopped.");
  806 + return 0;
  807 + } else if (a == QLatin1String("-p") || a == QLatin1String("-pause")) {
  808 + d_ptr->controller.pause();
  809 + return 0;
  810 + } else if (a == QLatin1String("-r") || a == QLatin1String("-resume")) {
  811 + d_ptr->controller.resume();
  812 + return 0;
  813 + } else if (a == QLatin1String("-c") || a == QLatin1String("-command")) {
  814 + int code = 0;
  815 + if (d_ptr->args.size() > 2)
  816 + code = d_ptr->args.at(2).toInt();
  817 + d_ptr->controller.sendCommand(code);
  818 + return 0;
  819 + } else if (a == QLatin1String("-h") || a == QLatin1String("-help")) {
  820 + printf("\n%s -[i|u|e|s|v|h]\n"
  821 + "\t-i(nstall) [account] [password]\t: Install the service, optionally using given account and password\n"
  822 + "\t-u(ninstall)\t: Uninstall the service.\n"
  823 + "\t-e(xec)\t\t: Run as a regular application. Useful for debugging.\n"
  824 + "\t-t(erminate)\t: Stop the service.\n"
  825 + "\t-c(ommand) num\t: Send command code num to the service.\n"
  826 + "\t-v(ersion)\t: Print version and status information.\n"
  827 + "\t-h(elp) \t: Show this help\n"
  828 + "\tNo arguments\t: Start the service.\n",
  829 + d_ptr->args.at(0).toLatin1().constData());
  830 + return 0;
  831 + }
  832 + }
  833 +#if defined(Q_OS_UNIX)
  834 + if (::getenv("QTSERVICE_RUN")) {
  835 + // Means we're the detached, real service process.
  836 + int ec = d_ptr->run(true, d_ptr->args);
  837 + if (ec == -1)
  838 + qErrnoWarning("The service failed to run.");
  839 + return ec;
  840 + }
  841 +#endif
  842 + if (!d_ptr->start()) {
  843 + fprintf(stderr, "The service %s could not start\n", serviceName().toLatin1().constData());
  844 + return -4;
  845 + }
  846 + return 0;
  847 +}
  848 +
  849 +/*!
  850 + \fn void QtServiceBase::logMessage(const QString &message, MessageType type,
  851 + int id, uint category, const QByteArray &data)
  852 +
  853 + Reports a message of the given \a type with the given \a message
  854 + to the local system event log. The message identifier \a id and
  855 + the message \a category are user defined values. The \a data
  856 + parameter can contain arbitrary binary data.
  857 +
  858 + Message strings for \a id and \a category must be provided by a
  859 + message file, which must be registered in the system registry.
  860 + Refer to the MSDN for more information about how to do this on
  861 + Windows.
  862 +
  863 + \sa MessageType
  864 +*/
  865 +
  866 +/*!
  867 + Returns a pointer to the current application's QtServiceBase
  868 + instance.
  869 +*/
  870 +QtServiceBase *QtServiceBase::instance()
  871 +{
  872 + return QtServiceBasePrivate::instance;
  873 +}
  874 +
  875 +/*!
  876 + \fn void QtServiceBase::start()
  877 +
  878 + This function must be implemented in QtServiceBase subclasses in
  879 + order to perform the service's work. Usually you create some main
  880 + object on the heap which is the heart of your service.
  881 +
  882 + The function is only called when no service specific arguments
  883 + were passed to the service constructor, and is called by exec()
  884 + after it has called the executeApplication() function.
  885 +
  886 + Note that you \e don't need to create an application object or
  887 + call its exec() function explicitly.
  888 +
  889 + \sa exec(), stop(), QtServiceController::start()
  890 +*/
  891 +
  892 +/*!
  893 + Reimplement this function to perform additional cleanups before
  894 + shutting down (for example deleting a main object if it was
  895 + created in the start() function).
  896 +
  897 + This function is called in reply to controller requests. The
  898 + default implementation does nothing.
  899 +
  900 + \sa start(), QtServiceController::stop()
  901 +*/
  902 +void QtServiceBase::stop()
  903 +{
  904 +}
  905 +
  906 +/*!
  907 + Reimplement this function to pause the service's execution (for
  908 + example to stop a polling timer, or to ignore socket notifiers).
  909 +
  910 + This function is called in reply to controller requests. The
  911 + default implementation does nothing.
  912 +
  913 + \sa resume(), QtServiceController::pause()
  914 +*/
  915 +void QtServiceBase::pause()
  916 +{
  917 +}
  918 +
  919 +/*!
  920 + Reimplement this function to continue the service after a call to
  921 + pause().
  922 +
  923 + This function is called in reply to controller requests. The
  924 + default implementation does nothing.
  925 +
  926 + \sa pause(), QtServiceController::resume()
  927 +*/
  928 +void QtServiceBase::resume()
  929 +{
  930 +}
  931 +
  932 +/*!
  933 + Reimplement this function to process the user command \a code.
  934 +
  935 +
  936 + This function is called in reply to controller requests. The
  937 + default implementation does nothing.
  938 +
  939 + \sa QtServiceController::sendCommand()
  940 +*/
  941 +void QtServiceBase::processCommand(int /*code*/)
  942 +{
  943 +}
  944 +
  945 +/*!
  946 + \fn void QtServiceBase::createApplication(int &argc, char **argv)
  947 +
  948 + Creates the application object using the \a argc and \a argv
  949 + parameters.
  950 +
  951 + This function is only called when no \l
  952 + {serviceSpecificArguments}{service specific arguments} were
  953 + passed to the service constructor, and is called by exec() before
  954 + it calls the executeApplication() and start() functions.
  955 +
  956 + The createApplication() function is implemented in QtService, but
  957 + you might want to reimplement it, for example, if the chosen
  958 + application type's constructor needs additional arguments.
  959 +
  960 + \sa exec(), QtService
  961 +*/
  962 +
  963 +/*!
  964 + \fn int QtServiceBase::executeApplication()
  965 +
  966 + Executes the application previously created with the
  967 + createApplication() function.
  968 +
  969 + This function is only called when no \l
  970 + {serviceSpecificArguments}{service specific arguments} were
  971 + passed to the service constructor, and is called by exec() after
  972 + it has called the createApplication() function and before start() function.
  973 +
  974 + This function is implemented in QtService.
  975 +
  976 + \sa exec(), createApplication()
  977 +*/
  978 +
  979 +/*!
  980 + \class QtService
  981 +
  982 + \brief The QtService is a convenient template class that allows
  983 + you to create a service for a particular application type.
  984 +
  985 + A Windows service or Unix daemon (a "service"), is a program that
  986 + runs "in the background" independently of whether a user is logged
  987 + in or not. A service is often set up to start when the machine
  988 + boots up, and will typically run continuously as long as the
  989 + machine is on.
  990 +
  991 + Services are usually non-interactive console applications. User
  992 + interaction, if required, is usually implemented in a separate,
  993 + normal GUI application that communicates with the service through
  994 + an IPC channel. For simple communication,
  995 + QtServiceController::sendCommand() and QtService::processCommand()
  996 + may be used, possibly in combination with a shared settings file. For
  997 + more complex, interactive communication, a custom IPC channel
  998 + should be used, e.g. based on Qt's networking classes. (In certain
  999 + circumstances, a service may provide a GUI itself, ref. the
  1000 + "interactive" example documentation).
  1001 +
  1002 + \bold{Note:} On Unix systems, this class relies on facilities
  1003 + provided by the QtNetwork module, provided as part of the
  1004 + \l{Qt Open Source Edition} and certain \l{Qt Commercial Editions}.
  1005 +
  1006 + The QtService class functionality is inherited from QtServiceBase,
  1007 + but in addition the QtService class binds an instance of
  1008 + QtServiceBase with an application type.
  1009 +
  1010 + Typically, you will create a service by subclassing the QtService
  1011 + template class. For example:
  1012 +
  1013 + \code
  1014 + class MyService : public QtService<QApplication>
  1015 + {
  1016 + public:
  1017 + MyService(int argc, char **argv);
  1018 + ~MyService();
  1019 +
  1020 + protected:
  1021 + void start();
  1022 + void stop();
  1023 + void pause();
  1024 + void resume();
  1025 + void processCommand(int code);
  1026 + };
  1027 + \endcode
  1028 +
  1029 + The application type can be QCoreApplication for services without
  1030 + GUI, QApplication for services with GUI or you can use your own
  1031 + custom application type.
  1032 +
  1033 + You must reimplement the QtServiceBase::start() function to
  1034 + perform the service's work. Usually you create some main object on
  1035 + the heap which is the heart of your service.
  1036 +
  1037 + In addition, you might want to reimplement the
  1038 + QtServiceBase::pause(), QtServiceBase::processCommand(),
  1039 + QtServiceBase::resume() and QtServiceBase::stop() to intervene the
  1040 + service's process on controller requests. You can control any
  1041 + given service using an instance of the QtServiceController class
  1042 + which also allows you to control services from separate
  1043 + applications. The mentioned functions are all virtual and won't do
  1044 + anything unless they are reimplemented.
  1045 +
  1046 + Your custom service is typically instantiated in the application's
  1047 + main function. Then the main function will call your service's
  1048 + exec() function, and return the result of that call. For example:
  1049 +
  1050 + \code
  1051 + int main(int argc, char **argv)
  1052 + {
  1053 + MyService service(argc, argv);
  1054 + return service.exec();
  1055 + }
  1056 + \endcode
  1057 +
  1058 + When the exec() function is called, it will parse the \l
  1059 + {serviceSpecificArguments} {service specific arguments} passed in
  1060 + \c argv, perform the required actions, and exit.
  1061 +
  1062 + If none of the arguments is recognized as service specific, exec()
  1063 + will first call the createApplication() function, then executeApplication() and
  1064 + finally the start() function. In the end, exec()
  1065 + returns while the service continues in its own process waiting for
  1066 + commands from the service controller.
  1067 +
  1068 + \sa QtServiceBase, QtServiceController
  1069 +*/
  1070 +
  1071 +/*!
  1072 + \fn QtService::QtService(int argc, char **argv, const QString &name)
  1073 +
  1074 + Constructs a QtService object called \a name. The \a argc and \a
  1075 + argv parameters are parsed after the exec() function has been
  1076 + called. Then they are passed to the application's constructor.
  1077 +
  1078 + There can only be one QtService object in a process.
  1079 +
  1080 + \sa QtServiceBase()
  1081 +*/
  1082 +
  1083 +/*!
  1084 + \fn QtService::~QtService()
  1085 +
  1086 + Destroys the service object.
  1087 +*/
  1088 +
  1089 +/*!
  1090 + \fn Application *QtService::application() const
  1091 +
  1092 + Returns a pointer to the application object.
  1093 +*/
  1094 +
  1095 +/*!
  1096 + \fn void QtService::createApplication(int &argc, char **argv)
  1097 +
  1098 + Creates application object of type Application passing \a argc and
  1099 + \a argv to its constructor.
  1100 +
  1101 + \reimp
  1102 +
  1103 +*/
  1104 +
  1105 +/*!
  1106 + \fn int QtService::executeApplication()
  1107 +
  1108 + \reimp
  1109 +*/
  1110 +
  1111 +
  1112 +
... ...
src/qtservice/src/qtservice.h 0 → 100644
... ... @@ -0,0 +1,192 @@
  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 <QCoreApplication>
  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 <typename Application>
  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
... ...
src/qtservice/src/qtservice.pri 0 → 100644
... ... @@ -0,0 +1,21 @@
  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 +}
... ...
src/qtservice/src/qtservice_p.h 0 → 100644
... ... @@ -0,0 +1,87 @@
  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 <QStringList>
  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
... ...
src/qtservice/src/qtservice_unix.cpp 0 → 100644
... ... @@ -0,0 +1,474 @@
  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 "qtservice.h"
  42 +#include "qtservice_p.h"
  43 +#include "qtunixsocket.h"
  44 +#include "qtunixserversocket.h"
  45 +#include <QCoreApplication>
  46 +#include <QStringList>
  47 +#include <QFile>
  48 +#include <QTimer>
  49 +#include <QDir>
  50 +#include <pwd.h>
  51 +#include <fcntl.h>
  52 +#include <unistd.h>
  53 +#include <stdlib.h>
  54 +#include <string.h>
  55 +#include <syslog.h>
  56 +#include <signal.h>
  57 +#include <sys/stat.h>
  58 +#include <QMap>
  59 +#include <QSettings>
  60 +#include <QProcess>
  61 +
  62 +static QString encodeName(const QString &name, bool allowUpper = false)
  63 +{
  64 + QString n = name.toLower();
  65 + QString legal = QLatin1String("abcdefghijklmnopqrstuvwxyz1234567890");
  66 + if (allowUpper)
  67 + legal += QLatin1String("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  68 + int pos = 0;
  69 + while (pos < n.size()) {
  70 + if (legal.indexOf(n[pos]) == -1)
  71 + n.remove(pos, 1);
  72 + else
  73 + ++pos;
  74 + }
  75 + return n;
  76 +}
  77 +
  78 +static QString login()
  79 +{
  80 + QString l;
  81 + uid_t uid = getuid();
  82 + passwd *pw = getpwuid(uid);
  83 + if (pw)
  84 + l = QString(pw->pw_name);
  85 + return l;
  86 +}
  87 +
  88 +static QString socketPath(const QString &serviceName)
  89 +{
  90 + QString sn = encodeName(serviceName);
  91 + return QString(QLatin1String("/var/tmp/") + sn + QLatin1String(".") + login());
  92 +}
  93 +
  94 +static bool sendCmd(const QString &serviceName, const QString &cmd)
  95 +{
  96 + bool retValue = false;
  97 + QtUnixSocket sock;
  98 + if (sock.connectTo(socketPath(serviceName))) {
  99 + sock.write(QString(cmd+"\r\n").toLatin1().constData());
  100 + sock.flush();
  101 + sock.waitForReadyRead(-1);
  102 + QString reply = sock.readAll();
  103 + if (reply == QLatin1String("true"))
  104 + retValue = true;
  105 + sock.close();
  106 + }
  107 + return retValue;
  108 +}
  109 +
  110 +static QString absPath(const QString &path)
  111 +{
  112 + QString ret;
  113 + if (path[0] != QChar('/')) { // Not an absolute path
  114 + int slashpos;
  115 + if ((slashpos = path.lastIndexOf('/')) != -1) { // Relative path
  116 + QDir dir = QDir::current();
  117 + dir.cd(path.left(slashpos));
  118 + ret = dir.absolutePath();
  119 + } else { // Need to search $PATH
  120 + char *envPath = ::getenv("PATH");
  121 + if (envPath) {
  122 + QStringList envPaths = QString::fromLocal8Bit(envPath).split(':');
  123 + for (int i = 0; i < envPaths.size(); ++i) {
  124 + if (QFile::exists(envPaths.at(i) + QLatin1String("/") + QString(path))) {
  125 + QDir dir(envPaths.at(i));
  126 + ret = dir.absolutePath();
  127 + break;
  128 + }
  129 + }
  130 + }
  131 + }
  132 + } else {
  133 + QFileInfo fi(path);
  134 + ret = fi.absolutePath();
  135 + }
  136 + return ret;
  137 +}
  138 +
  139 +QString QtServiceBasePrivate::filePath() const
  140 +{
  141 + QString ret;
  142 + if (args.isEmpty())
  143 + return ret;
  144 + QFileInfo fi(args[0]);
  145 + QDir dir(absPath(args[0]));
  146 + return dir.absoluteFilePath(fi.fileName());
  147 +}
  148 +
  149 +
  150 +QString QtServiceController::serviceDescription() const
  151 +{
  152 + QSettings settings(QSettings::SystemScope, "QtSoftware");
  153 + settings.beginGroup("services");
  154 + settings.beginGroup(serviceName());
  155 +
  156 + QString desc = settings.value("description").toString();
  157 +
  158 + settings.endGroup();
  159 + settings.endGroup();
  160 +
  161 + return desc;
  162 +}
  163 +
  164 +QtServiceController::StartupType QtServiceController::startupType() const
  165 +{
  166 + QSettings settings(QSettings::SystemScope, "QtSoftware");
  167 + settings.beginGroup("services");
  168 + settings.beginGroup(serviceName());
  169 +
  170 + StartupType startupType = (StartupType)settings.value("startupType").toInt();
  171 +
  172 + settings.endGroup();
  173 + settings.endGroup();
  174 +
  175 + return startupType;
  176 +}
  177 +
  178 +QString QtServiceController::serviceFilePath() const
  179 +{
  180 + QSettings settings(QSettings::SystemScope, "QtSoftware");
  181 + settings.beginGroup("services");
  182 + settings.beginGroup(serviceName());
  183 +
  184 + QString path = settings.value("path").toString();
  185 +
  186 + settings.endGroup();
  187 + settings.endGroup();
  188 +
  189 + return path;
  190 +}
  191 +
  192 +bool QtServiceController::uninstall()
  193 +{
  194 + QSettings settings(QSettings::SystemScope, "QtSoftware");
  195 + settings.beginGroup("services");
  196 +
  197 + settings.remove(serviceName());
  198 +
  199 + settings.endGroup();
  200 + settings.sync();
  201 +
  202 + QSettings::Status ret = settings.status();
  203 + if (ret == QSettings::AccessError) {
  204 + fprintf(stderr, "Cannot uninstall \"%s\". Cannot write to: %s. Check permissions.\n",
  205 + serviceName().toLatin1().constData(),
  206 + settings.fileName().toLatin1().constData());
  207 + }
  208 + return (ret == QSettings::NoError);
  209 +}
  210 +
  211 +
  212 +bool QtServiceController::start(const QStringList &arguments)
  213 +{
  214 + if (!isInstalled())
  215 + return false;
  216 + if (isRunning())
  217 + return false;
  218 + return QProcess::startDetached(serviceFilePath(), arguments);
  219 +}
  220 +
  221 +bool QtServiceController::stop()
  222 +{
  223 + return sendCmd(serviceName(), QLatin1String("terminate"));
  224 +}
  225 +
  226 +bool QtServiceController::pause()
  227 +{
  228 + return sendCmd(serviceName(), QLatin1String("pause"));
  229 +}
  230 +
  231 +bool QtServiceController::resume()
  232 +{
  233 + return sendCmd(serviceName(), QLatin1String("resume"));
  234 +}
  235 +
  236 +bool QtServiceController::sendCommand(int code)
  237 +{
  238 + return sendCmd(serviceName(), QString(QLatin1String("num:") + QString::number(code)));
  239 +}
  240 +
  241 +bool QtServiceController::isInstalled() const
  242 +{
  243 + QSettings settings(QSettings::SystemScope, "QtSoftware");
  244 + settings.beginGroup("services");
  245 +
  246 + QStringList list = settings.childGroups();
  247 +
  248 + settings.endGroup();
  249 +
  250 + QStringListIterator it(list);
  251 + while (it.hasNext()) {
  252 + if (it.next() == serviceName())
  253 + return true;
  254 + }
  255 +
  256 + return false;
  257 +}
  258 +
  259 +bool QtServiceController::isRunning() const
  260 +{
  261 + QtUnixSocket sock;
  262 + if (sock.connectTo(socketPath(serviceName())))
  263 + return true;
  264 + return false;
  265 +}
  266 +
  267 +
  268 +
  269 +
  270 +///////////////////////////////////
  271 +
  272 +class QtServiceSysPrivate : public QtUnixServerSocket
  273 +{
  274 + Q_OBJECT
  275 +public:
  276 + QtServiceSysPrivate();
  277 + ~QtServiceSysPrivate();
  278 +
  279 + char *ident;
  280 +
  281 + QtServiceBase::ServiceFlags serviceFlags;
  282 +
  283 +protected:
  284 + void incomingConnection(int socketDescriptor);
  285 +
  286 +private slots:
  287 + void slotReady();
  288 + void slotClosed();
  289 +
  290 +private:
  291 + QString getCommand(const QTcpSocket *socket);
  292 + QMap<const QTcpSocket *, QString> cache;
  293 +};
  294 +
  295 +QtServiceSysPrivate::QtServiceSysPrivate()
  296 + : QtUnixServerSocket(), ident(0), serviceFlags(0)
  297 +{
  298 +}
  299 +
  300 +QtServiceSysPrivate::~QtServiceSysPrivate()
  301 +{
  302 + if (ident)
  303 + delete[] ident;
  304 +}
  305 +
  306 +void QtServiceSysPrivate::incomingConnection(int socketDescriptor)
  307 +{
  308 + QTcpSocket *s = new QTcpSocket(this);
  309 + s->setSocketDescriptor(socketDescriptor);
  310 + connect(s, SIGNAL(readyRead()), this, SLOT(slotReady()));
  311 + connect(s, SIGNAL(disconnected()), this, SLOT(slotClosed()));
  312 +}
  313 +
  314 +void QtServiceSysPrivate::slotReady()
  315 +{
  316 + QTcpSocket *s = (QTcpSocket *)sender();
  317 + cache[s] += QString(s->readAll());
  318 + QString cmd = getCommand(s);
  319 + while (!cmd.isEmpty()) {
  320 + bool retValue = false;
  321 + if (cmd == QLatin1String("terminate")) {
  322 + if (!(serviceFlags & QtServiceBase::CannotBeStopped)) {
  323 + QtServiceBase::instance()->stop();
  324 + QCoreApplication::instance()->quit();
  325 + retValue = true;
  326 + }
  327 + } else if (cmd == QLatin1String("pause")) {
  328 + if (serviceFlags & QtServiceBase::CanBeSuspended) {
  329 + QtServiceBase::instance()->pause();
  330 + retValue = true;
  331 + }
  332 + } else if (cmd == QLatin1String("resume")) {
  333 + if (serviceFlags & QtServiceBase::CanBeSuspended) {
  334 + QtServiceBase::instance()->resume();
  335 + retValue = true;
  336 + }
  337 + } else if (cmd == QLatin1String("alive")) {
  338 + retValue = true;
  339 + } else if (cmd.length() > 4 && cmd.left(4) == QLatin1String("num:")) {
  340 + cmd = cmd.mid(4);
  341 + QtServiceBase::instance()->processCommand(cmd.toInt());
  342 + retValue = true;
  343 + }
  344 + QString retString;
  345 + if (retValue)
  346 + retString = QLatin1String("true");
  347 + else
  348 + retString = QLatin1String("false");
  349 + s->write(retString.toLatin1().constData());
  350 + s->flush();
  351 + cmd = getCommand(s);
  352 + }
  353 +}
  354 +
  355 +void QtServiceSysPrivate::slotClosed()
  356 +{
  357 + QTcpSocket *s = (QTcpSocket *)sender();
  358 + s->deleteLater();
  359 +}
  360 +
  361 +QString QtServiceSysPrivate::getCommand(const QTcpSocket *socket)
  362 +{
  363 + int pos = cache[socket].indexOf("\r\n");
  364 + if (pos >= 0) {
  365 + QString ret = cache[socket].left(pos);
  366 + cache[socket].remove(0, pos+2);
  367 + return ret;
  368 + }
  369 + return "";
  370 +}
  371 +
  372 +#include "qtservice_unix.moc"
  373 +
  374 +bool QtServiceBasePrivate::sysInit()
  375 +{
  376 + sysd = new QtServiceSysPrivate;
  377 + sysd->serviceFlags = serviceFlags;
  378 + // Restrict permissions on files that are created by the service
  379 + ::umask(027);
  380 +
  381 + return true;
  382 +}
  383 +
  384 +void QtServiceBasePrivate::sysSetPath()
  385 +{
  386 + if (sysd)
  387 + sysd->setPath(socketPath(controller.serviceName()));
  388 +}
  389 +
  390 +void QtServiceBasePrivate::sysCleanup()
  391 +{
  392 + if (sysd) {
  393 + sysd->close();
  394 + delete sysd;
  395 + sysd = 0;
  396 + }
  397 +}
  398 +
  399 +bool QtServiceBasePrivate::start()
  400 +{
  401 + if (sendCmd(controller.serviceName(), "alive")) {
  402 + // Already running
  403 + return false;
  404 + }
  405 + // Could just call controller.start() here, but that would fail if
  406 + // we're not installed. We do not want to strictly require installation.
  407 + ::setenv("QTSERVICE_RUN", "1", 1); // Tell the detached process it's it
  408 + return QProcess::startDetached(filePath(), args.mid(1), "/");
  409 +}
  410 +
  411 +bool QtServiceBasePrivate::install(const QString &account, const QString &password)
  412 +{
  413 + Q_UNUSED(account)
  414 + Q_UNUSED(password)
  415 + QSettings settings(QSettings::SystemScope, "QtSoftware");
  416 +
  417 + settings.beginGroup("services");
  418 + settings.beginGroup(controller.serviceName());
  419 +
  420 + settings.setValue("path", filePath());
  421 + settings.setValue("description", serviceDescription);
  422 + settings.setValue("automaticStartup", startupType);
  423 +
  424 + settings.endGroup();
  425 + settings.endGroup();
  426 + settings.sync();
  427 +
  428 + QSettings::Status ret = settings.status();
  429 + if (ret == QSettings::AccessError) {
  430 + fprintf(stderr, "Cannot install \"%s\". Cannot write to: %s. Check permissions.\n",
  431 + controller.serviceName().toLatin1().constData(),
  432 + settings.fileName().toLatin1().constData());
  433 + }
  434 + return (ret == QSettings::NoError);
  435 +}
  436 +
  437 +void QtServiceBase::logMessage(const QString &message, QtServiceBase::MessageType type,
  438 + int, uint, const QByteArray &)
  439 +{
  440 + if (!d_ptr->sysd)
  441 + return;
  442 + int st;
  443 + switch(type) {
  444 + case QtServiceBase::Error:
  445 + st = LOG_ERR;
  446 + break;
  447 + case QtServiceBase::Warning:
  448 + st = LOG_WARNING;
  449 + break;
  450 + default:
  451 + st = LOG_INFO;
  452 + }
  453 + if (!d_ptr->sysd->ident) {
  454 + QString tmp = encodeName(serviceName(), true);
  455 + int len = tmp.toLocal8Bit().size();
  456 + d_ptr->sysd->ident = new char[len+1];
  457 + d_ptr->sysd->ident[len] = '\0';
  458 + ::memcpy(d_ptr->sysd->ident, tmp.toLocal8Bit().constData(), len);
  459 + }
  460 + openlog(d_ptr->sysd->ident, LOG_PID, LOG_DAEMON);
  461 + foreach(QString line, message.split('\n'))
  462 + syslog(st, "%s", line.toLocal8Bit().constData());
  463 + closelog();
  464 +}
  465 +
  466 +void QtServiceBase::setServiceFlags(QtServiceBase::ServiceFlags flags)
  467 +{
  468 + if (d_ptr->serviceFlags == flags)
  469 + return;
  470 + d_ptr->serviceFlags = flags;
  471 + if (d_ptr->sysd)
  472 + d_ptr->sysd->serviceFlags = flags;
  473 +}
  474 +
... ...
src/qtservice/src/qtservice_win.cpp 0 → 100644
... ... @@ -0,0 +1,945 @@
  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 "qtservice.h"
  42 +#include "qtservice_p.h"
  43 +#include <QCoreApplication>
  44 +#include <QDateTime>
  45 +#include <QFile>
  46 +#include <QLibrary>
  47 +#include <QMutex>
  48 +#include <QSemaphore>
  49 +#include <QProcess>
  50 +#include <QSettings>
  51 +#include <QTextStream>
  52 +#include <qt_windows.h>
  53 +#include <QWaitCondition>
  54 +#include <QAbstractEventDispatcher>
  55 +#include <QVector>
  56 +#include <QThread>
  57 +#if QT_VERSION >= 0x050000
  58 +# include <QAbstractNativeEventFilter>
  59 +#endif
  60 +#include <stdio.h>
  61 +#if defined(QTSERVICE_DEBUG)
  62 +#include <QDebug>
  63 +#endif
  64 +
  65 +typedef SERVICE_STATUS_HANDLE(WINAPI*PRegisterServiceCtrlHandler)(const wchar_t*,LPHANDLER_FUNCTION);
  66 +static PRegisterServiceCtrlHandler pRegisterServiceCtrlHandler = 0;
  67 +typedef BOOL(WINAPI*PSetServiceStatus)(SERVICE_STATUS_HANDLE,LPSERVICE_STATUS);
  68 +static PSetServiceStatus pSetServiceStatus = 0;
  69 +typedef BOOL(WINAPI*PChangeServiceConfig2)(SC_HANDLE,DWORD,LPVOID);
  70 +static PChangeServiceConfig2 pChangeServiceConfig2 = 0;
  71 +typedef BOOL(WINAPI*PCloseServiceHandle)(SC_HANDLE);
  72 +static PCloseServiceHandle pCloseServiceHandle = 0;
  73 +typedef SC_HANDLE(WINAPI*PCreateService)(SC_HANDLE,LPCTSTR,LPCTSTR,DWORD,DWORD,DWORD,DWORD,LPCTSTR,LPCTSTR,LPDWORD,LPCTSTR,LPCTSTR,LPCTSTR);
  74 +static PCreateService pCreateService = 0;
  75 +typedef SC_HANDLE(WINAPI*POpenSCManager)(LPCTSTR,LPCTSTR,DWORD);
  76 +static POpenSCManager pOpenSCManager = 0;
  77 +typedef BOOL(WINAPI*PDeleteService)(SC_HANDLE);
  78 +static PDeleteService pDeleteService = 0;
  79 +typedef SC_HANDLE(WINAPI*POpenService)(SC_HANDLE,LPCTSTR,DWORD);
  80 +static POpenService pOpenService = 0;
  81 +typedef BOOL(WINAPI*PQueryServiceStatus)(SC_HANDLE,LPSERVICE_STATUS);
  82 +static PQueryServiceStatus pQueryServiceStatus = 0;
  83 +typedef BOOL(WINAPI*PStartServiceCtrlDispatcher)(CONST SERVICE_TABLE_ENTRY*);
  84 +static PStartServiceCtrlDispatcher pStartServiceCtrlDispatcher = 0;
  85 +typedef BOOL(WINAPI*PStartService)(SC_HANDLE,DWORD,const wchar_t**);
  86 +static PStartService pStartService = 0;
  87 +typedef BOOL(WINAPI*PControlService)(SC_HANDLE,DWORD,LPSERVICE_STATUS);
  88 +static PControlService pControlService = 0;
  89 +typedef HANDLE(WINAPI*PDeregisterEventSource)(HANDLE);
  90 +static PDeregisterEventSource pDeregisterEventSource = 0;
  91 +typedef BOOL(WINAPI*PReportEvent)(HANDLE,WORD,WORD,DWORD,PSID,WORD,DWORD,LPCTSTR*,LPVOID);
  92 +static PReportEvent pReportEvent = 0;
  93 +typedef HANDLE(WINAPI*PRegisterEventSource)(LPCTSTR,LPCTSTR);
  94 +static PRegisterEventSource pRegisterEventSource = 0;
  95 +typedef DWORD(WINAPI*PRegisterServiceProcess)(DWORD,DWORD);
  96 +static PRegisterServiceProcess pRegisterServiceProcess = 0;
  97 +typedef BOOL(WINAPI*PQueryServiceConfig)(SC_HANDLE,LPQUERY_SERVICE_CONFIG,DWORD,LPDWORD);
  98 +static PQueryServiceConfig pQueryServiceConfig = 0;
  99 +typedef BOOL(WINAPI*PQueryServiceConfig2)(SC_HANDLE,DWORD,LPBYTE,DWORD,LPDWORD);
  100 +static PQueryServiceConfig2 pQueryServiceConfig2 = 0;
  101 +
  102 +
  103 +#define RESOLVE(name) p##name = (P##name)lib.resolve(#name);
  104 +#define RESOLVEA(name) p##name = (P##name)lib.resolve(#name"A");
  105 +#define RESOLVEW(name) p##name = (P##name)lib.resolve(#name"W");
  106 +
  107 +static bool winServiceInit()
  108 +{
  109 + if (!pOpenSCManager) {
  110 + QLibrary lib("advapi32");
  111 +
  112 + // only resolve unicode versions
  113 + RESOLVEW(RegisterServiceCtrlHandler);
  114 + RESOLVE(SetServiceStatus);
  115 + RESOLVEW(ChangeServiceConfig2);
  116 + RESOLVE(CloseServiceHandle);
  117 + RESOLVEW(CreateService);
  118 + RESOLVEW(OpenSCManager);
  119 + RESOLVE(DeleteService);
  120 + RESOLVEW(OpenService);
  121 + RESOLVE(QueryServiceStatus);
  122 + RESOLVEW(StartServiceCtrlDispatcher);
  123 + RESOLVEW(StartService); // need only Ansi version
  124 + RESOLVE(ControlService);
  125 + RESOLVE(DeregisterEventSource);
  126 + RESOLVEW(ReportEvent);
  127 + RESOLVEW(RegisterEventSource);
  128 + RESOLVEW(QueryServiceConfig);
  129 + RESOLVEW(QueryServiceConfig2);
  130 + }
  131 + return pOpenSCManager != 0;
  132 +}
  133 +
  134 +bool QtServiceController::isInstalled() const
  135 +{
  136 + Q_D(const QtServiceController);
  137 + bool result = false;
  138 + if (!winServiceInit())
  139 + return result;
  140 +
  141 + // Open the Service Control Manager
  142 + SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
  143 + if (hSCM) {
  144 + // Try to open the service
  145 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t*)d->serviceName.utf16(),
  146 + SERVICE_QUERY_CONFIG);
  147 +
  148 + if (hService) {
  149 + result = true;
  150 + pCloseServiceHandle(hService);
  151 + }
  152 + pCloseServiceHandle(hSCM);
  153 + }
  154 + return result;
  155 +}
  156 +
  157 +bool QtServiceController::isRunning() const
  158 +{
  159 + Q_D(const QtServiceController);
  160 + bool result = false;
  161 + if (!winServiceInit())
  162 + return result;
  163 +
  164 + // Open the Service Control Manager
  165 + SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
  166 + if (hSCM) {
  167 + // Try to open the service
  168 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
  169 + SERVICE_QUERY_STATUS);
  170 + if (hService) {
  171 + SERVICE_STATUS info;
  172 + int res = pQueryServiceStatus(hService, &info);
  173 + if (res)
  174 + result = info.dwCurrentState != SERVICE_STOPPED;
  175 + pCloseServiceHandle(hService);
  176 + }
  177 + pCloseServiceHandle(hSCM);
  178 + }
  179 + return result;
  180 +}
  181 +
  182 +
  183 +QString QtServiceController::serviceFilePath() const
  184 +{
  185 + Q_D(const QtServiceController);
  186 + QString result;
  187 + if (!winServiceInit())
  188 + return result;
  189 +
  190 + // Open the Service Control Manager
  191 + SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
  192 + if (hSCM) {
  193 + // Try to open the service
  194 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
  195 + SERVICE_QUERY_CONFIG);
  196 + if (hService) {
  197 + DWORD sizeNeeded = 0;
  198 + char data[8 * 1024];
  199 + if (pQueryServiceConfig(hService, (LPQUERY_SERVICE_CONFIG)data, 8 * 1024, &sizeNeeded)) {
  200 + LPQUERY_SERVICE_CONFIG config = (LPQUERY_SERVICE_CONFIG)data;
  201 + result = QString::fromUtf16((const ushort*)config->lpBinaryPathName);
  202 + }
  203 + pCloseServiceHandle(hService);
  204 + }
  205 + pCloseServiceHandle(hSCM);
  206 + }
  207 + return result;
  208 +}
  209 +
  210 +QString QtServiceController::serviceDescription() const
  211 +{
  212 + Q_D(const QtServiceController);
  213 + QString result;
  214 + if (!winServiceInit())
  215 + return result;
  216 +
  217 + // Open the Service Control Manager
  218 + SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
  219 + if (hSCM) {
  220 + // Try to open the service
  221 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
  222 + SERVICE_QUERY_CONFIG);
  223 + if (hService) {
  224 + DWORD dwBytesNeeded;
  225 + char data[8 * 1024];
  226 + if (pQueryServiceConfig2(
  227 + hService,
  228 + SERVICE_CONFIG_DESCRIPTION,
  229 + (unsigned char *)data,
  230 + 8096,
  231 + &dwBytesNeeded)) {
  232 + LPSERVICE_DESCRIPTION desc = (LPSERVICE_DESCRIPTION)data;
  233 + if (desc->lpDescription)
  234 + result = QString::fromUtf16((const ushort*)desc->lpDescription);
  235 + }
  236 + pCloseServiceHandle(hService);
  237 + }
  238 + pCloseServiceHandle(hSCM);
  239 + }
  240 + return result;
  241 +}
  242 +
  243 +QtServiceController::StartupType QtServiceController::startupType() const
  244 +{
  245 + Q_D(const QtServiceController);
  246 + StartupType result = ManualStartup;
  247 + if (!winServiceInit())
  248 + return result;
  249 +
  250 + // Open the Service Control Manager
  251 + SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
  252 + if (hSCM) {
  253 + // Try to open the service
  254 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
  255 + SERVICE_QUERY_CONFIG);
  256 + if (hService) {
  257 + DWORD sizeNeeded = 0;
  258 + char data[8 * 1024];
  259 + if (pQueryServiceConfig(hService, (QUERY_SERVICE_CONFIG *)data, 8 * 1024, &sizeNeeded)) {
  260 + QUERY_SERVICE_CONFIG *config = (QUERY_SERVICE_CONFIG *)data;
  261 + result = config->dwStartType == SERVICE_DEMAND_START ? ManualStartup : AutoStartup;
  262 + }
  263 + pCloseServiceHandle(hService);
  264 + }
  265 + pCloseServiceHandle(hSCM);
  266 + }
  267 + return result;
  268 +}
  269 +
  270 +bool QtServiceController::uninstall()
  271 +{
  272 + Q_D(QtServiceController);
  273 + bool result = false;
  274 + if (!winServiceInit())
  275 + return result;
  276 +
  277 + // Open the Service Control Manager
  278 + SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
  279 + if (hSCM) {
  280 + // Try to open the service
  281 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(), DELETE);
  282 + if (hService) {
  283 + if (pDeleteService(hService))
  284 + result = true;
  285 + pCloseServiceHandle(hService);
  286 + }
  287 + pCloseServiceHandle(hSCM);
  288 + }
  289 + return result;
  290 +}
  291 +
  292 +bool QtServiceController::start(const QStringList &args)
  293 +{
  294 + Q_D(QtServiceController);
  295 + bool result = false;
  296 + if (!winServiceInit())
  297 + return result;
  298 +
  299 + // Open the Service Control Manager
  300 + SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
  301 + if (hSCM) {
  302 + // Try to open the service
  303 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(), SERVICE_START);
  304 + if (hService) {
  305 + QVector<const wchar_t *> argv(args.size());
  306 + for (int i = 0; i < args.size(); ++i)
  307 + argv[i] = (const wchar_t*)args.at(i).utf16();
  308 +
  309 + if (pStartService(hService, args.size(), argv.data()))
  310 + result = true;
  311 + pCloseServiceHandle(hService);
  312 + }
  313 + pCloseServiceHandle(hSCM);
  314 + }
  315 + return result;
  316 +}
  317 +
  318 +bool QtServiceController::stop()
  319 +{
  320 + Q_D(QtServiceController);
  321 + bool result = false;
  322 + if (!winServiceInit())
  323 + return result;
  324 +
  325 + SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
  326 + if (hSCM) {
  327 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(), SERVICE_STOP|SERVICE_QUERY_STATUS);
  328 + if (hService) {
  329 + SERVICE_STATUS status;
  330 + if (pControlService(hService, SERVICE_CONTROL_STOP, &status)) {
  331 + bool stopped = status.dwCurrentState == SERVICE_STOPPED;
  332 + int i = 0;
  333 + while(!stopped && i < 10) {
  334 + Sleep(200);
  335 + if (!pQueryServiceStatus(hService, &status))
  336 + break;
  337 + stopped = status.dwCurrentState == SERVICE_STOPPED;
  338 + ++i;
  339 + }
  340 + result = stopped;
  341 + } else {
  342 + qErrnoWarning(GetLastError(), "stopping");
  343 + }
  344 + pCloseServiceHandle(hService);
  345 + }
  346 + pCloseServiceHandle(hSCM);
  347 + }
  348 + return result;
  349 +}
  350 +
  351 +bool QtServiceController::pause()
  352 +{
  353 + Q_D(QtServiceController);
  354 + bool result = false;
  355 + if (!winServiceInit())
  356 + return result;
  357 +
  358 + SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
  359 + if (hSCM) {
  360 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
  361 + SERVICE_PAUSE_CONTINUE);
  362 + if (hService) {
  363 + SERVICE_STATUS status;
  364 + if (pControlService(hService, SERVICE_CONTROL_PAUSE, &status))
  365 + result = true;
  366 + pCloseServiceHandle(hService);
  367 + }
  368 + pCloseServiceHandle(hSCM);
  369 + }
  370 + return result;
  371 +}
  372 +
  373 +bool QtServiceController::resume()
  374 +{
  375 + Q_D(QtServiceController);
  376 + bool result = false;
  377 + if (!winServiceInit())
  378 + return result;
  379 +
  380 + SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
  381 + if (hSCM) {
  382 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
  383 + SERVICE_PAUSE_CONTINUE);
  384 + if (hService) {
  385 + SERVICE_STATUS status;
  386 + if (pControlService(hService, SERVICE_CONTROL_CONTINUE, &status))
  387 + result = true;
  388 + pCloseServiceHandle(hService);
  389 + }
  390 + pCloseServiceHandle(hSCM);
  391 + }
  392 + return result;
  393 +}
  394 +
  395 +bool QtServiceController::sendCommand(int code)
  396 +{
  397 + Q_D(QtServiceController);
  398 + bool result = false;
  399 + if (!winServiceInit())
  400 + return result;
  401 +
  402 + if (code < 0 || code > 127 || !isRunning())
  403 + return result;
  404 +
  405 + SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
  406 + if (hSCM) {
  407 + SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
  408 + SERVICE_USER_DEFINED_CONTROL);
  409 + if (hService) {
  410 + SERVICE_STATUS status;
  411 + if (pControlService(hService, 128 + code, &status))
  412 + result = true;
  413 + pCloseServiceHandle(hService);
  414 + }
  415 + pCloseServiceHandle(hSCM);
  416 + }
  417 + return result;
  418 +}
  419 +
  420 +#if defined(QTSERVICE_DEBUG)
  421 +extern void qtServiceLogDebug(QtMsgType type, const char* msg);
  422 +#endif
  423 +
  424 +void QtServiceBase::logMessage(const QString &message, MessageType type,
  425 + int id, uint category, const QByteArray &data)
  426 +{
  427 +#if defined(QTSERVICE_DEBUG)
  428 + QByteArray dbgMsg("[LOGGED ");
  429 + switch (type) {
  430 + case Error: dbgMsg += "Error] " ; break;
  431 + case Warning: dbgMsg += "Warning] "; break;
  432 + case Success: dbgMsg += "Success] "; break;
  433 + case Information: //fall through
  434 + default: dbgMsg += "Information] "; break;
  435 + }
  436 + dbgMsg += message.toAscii();
  437 + qtServiceLogDebug((QtMsgType)-1, dbgMsg.constData());
  438 +#endif
  439 +
  440 + Q_D(QtServiceBase);
  441 + if (!winServiceInit())
  442 + return;
  443 + WORD wType;
  444 + switch (type) {
  445 + case Error: wType = EVENTLOG_ERROR_TYPE; break;
  446 + case Warning: wType = EVENTLOG_WARNING_TYPE; break;
  447 + case Information: wType = EVENTLOG_INFORMATION_TYPE; break;
  448 + default: wType = EVENTLOG_SUCCESS; break;
  449 + }
  450 + HANDLE h = pRegisterEventSource(0, (wchar_t *)d->controller.serviceName().utf16());
  451 + if (h) {
  452 + const wchar_t *msg = (wchar_t*)message.utf16();
  453 + const char *bindata = data.size() ? data.constData() : 0;
  454 + pReportEvent(h, wType, category, id, 0, 1, data.size(),(const wchar_t **)&msg,
  455 + const_cast<char *>(bindata));
  456 + pDeregisterEventSource(h);
  457 + }
  458 +}
  459 +
  460 +class QtServiceControllerHandler : public QObject
  461 +{
  462 + Q_OBJECT
  463 +public:
  464 + QtServiceControllerHandler(QtServiceSysPrivate *sys);
  465 +
  466 +protected:
  467 + void customEvent(QEvent *e);
  468 +
  469 +private:
  470 + QtServiceSysPrivate *d_sys;
  471 +};
  472 +
  473 +class QtServiceSysPrivate
  474 +{
  475 +public:
  476 + enum {
  477 + QTSERVICE_STARTUP = 256
  478 + };
  479 + QtServiceSysPrivate();
  480 +
  481 + void setStatus( DWORD dwState );
  482 + void setServiceFlags(QtServiceBase::ServiceFlags flags);
  483 + DWORD serviceFlags(QtServiceBase::ServiceFlags flags) const;
  484 + inline bool available() const;
  485 + static void WINAPI serviceMain( DWORD dwArgc, wchar_t** lpszArgv );
  486 + static void WINAPI handler( DWORD dwOpcode );
  487 +
  488 + SERVICE_STATUS status;
  489 + SERVICE_STATUS_HANDLE serviceStatus;
  490 + QStringList serviceArgs;
  491 +
  492 + static QtServiceSysPrivate *instance;
  493 +#if QT_VERSION < 0x050000
  494 + static QCoreApplication::EventFilter nextFilter;
  495 +#endif
  496 +
  497 + QWaitCondition condition;
  498 + QMutex mutex;
  499 + QSemaphore startSemaphore;
  500 + QSemaphore startSemaphore2;
  501 +
  502 + QtServiceControllerHandler *controllerHandler;
  503 +
  504 + void handleCustomEvent(QEvent *e);
  505 +};
  506 +
  507 +QtServiceControllerHandler::QtServiceControllerHandler(QtServiceSysPrivate *sys)
  508 + : QObject(), d_sys(sys)
  509 +{
  510 +
  511 +}
  512 +
  513 +void QtServiceControllerHandler::customEvent(QEvent *e)
  514 +{
  515 + d_sys->handleCustomEvent(e);
  516 +}
  517 +
  518 +
  519 +QtServiceSysPrivate *QtServiceSysPrivate::instance = 0;
  520 +#if QT_VERSION < 0x050000
  521 +QCoreApplication::EventFilter QtServiceSysPrivate::nextFilter = 0;
  522 +#endif
  523 +
  524 +QtServiceSysPrivate::QtServiceSysPrivate()
  525 +{
  526 + instance = this;
  527 +}
  528 +
  529 +inline bool QtServiceSysPrivate::available() const
  530 +{
  531 + return 0 != pOpenSCManager;
  532 +}
  533 +
  534 +void WINAPI QtServiceSysPrivate::serviceMain(DWORD dwArgc, wchar_t** lpszArgv)
  535 +{
  536 + if (!instance || !QtServiceBase::instance())
  537 + return;
  538 +
  539 + // Windows spins off a random thread to call this function on
  540 + // startup, so here we just signal to the QApplication event loop
  541 + // in the main thread to go ahead with start()'ing the service.
  542 +
  543 + for (DWORD i = 0; i < dwArgc; i++)
  544 + instance->serviceArgs.append(QString::fromUtf16((unsigned short*)lpszArgv[i]));
  545 +
  546 + instance->startSemaphore.release(); // let the qapp creation start
  547 + instance->startSemaphore2.acquire(); // wait until its done
  548 + // Register the control request handler
  549 + instance->serviceStatus = pRegisterServiceCtrlHandler((TCHAR*)QtServiceBase::instance()->serviceName().utf16(), handler);
  550 +
  551 + if (!instance->serviceStatus) // cannot happen - something is utterly wrong
  552 + return;
  553 +
  554 + handler(QTSERVICE_STARTUP); // Signal startup to the application -
  555 + // causes QtServiceBase::start() to be called in the main thread
  556 +
  557 + // The MSDN doc says that this thread should just exit - the service is
  558 + // running in the main thread (here, via callbacks in the handler thread).
  559 +}
  560 +
  561 +
  562 +// The handler() is called from the thread that called
  563 +// StartServiceCtrlDispatcher, i.e. our HandlerThread, and
  564 +// not from the main thread that runs the event loop, so we
  565 +// have to post an event to ourselves, and use a QWaitCondition
  566 +// and a QMutex to synchronize.
  567 +void QtServiceSysPrivate::handleCustomEvent(QEvent *e)
  568 +{
  569 + int code = e->type() - QEvent::User;
  570 +
  571 + switch(code) {
  572 + case QTSERVICE_STARTUP: // Startup
  573 + QtServiceBase::instance()->start();
  574 + break;
  575 + case SERVICE_CONTROL_STOP:
  576 + QtServiceBase::instance()->stop();
  577 + QCoreApplication::instance()->quit();
  578 + break;
  579 + case SERVICE_CONTROL_PAUSE:
  580 + QtServiceBase::instance()->pause();
  581 + break;
  582 + case SERVICE_CONTROL_CONTINUE:
  583 + QtServiceBase::instance()->resume();
  584 + break;
  585 + default:
  586 + if (code >= 128 && code <= 255)
  587 + QtServiceBase::instance()->processCommand(code - 128);
  588 + break;
  589 + }
  590 +
  591 + mutex.lock();
  592 + condition.wakeAll();
  593 + mutex.unlock();
  594 +}
  595 +
  596 +void WINAPI QtServiceSysPrivate::handler( DWORD code )
  597 +{
  598 + if (!instance)
  599 + return;
  600 +
  601 + instance->mutex.lock();
  602 + switch (code) {
  603 + case QTSERVICE_STARTUP: // QtService startup (called from WinMain when started)
  604 + instance->setStatus(SERVICE_START_PENDING);
  605 + QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
  606 + instance->condition.wait(&instance->mutex);
  607 + instance->setStatus(SERVICE_RUNNING);
  608 + break;
  609 + case SERVICE_CONTROL_STOP: // 1
  610 + instance->setStatus(SERVICE_STOP_PENDING);
  611 + QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
  612 + instance->condition.wait(&instance->mutex);
  613 + // status will be reported as stopped by start() when qapp::exec returns
  614 + break;
  615 +
  616 + case SERVICE_CONTROL_PAUSE: // 2
  617 + instance->setStatus(SERVICE_PAUSE_PENDING);
  618 + QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
  619 + instance->condition.wait(&instance->mutex);
  620 + instance->setStatus(SERVICE_PAUSED);
  621 + break;
  622 +
  623 + case SERVICE_CONTROL_CONTINUE: // 3
  624 + instance->setStatus(SERVICE_CONTINUE_PENDING);
  625 + QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
  626 + instance->condition.wait(&instance->mutex);
  627 + instance->setStatus(SERVICE_RUNNING);
  628 + break;
  629 +
  630 + case SERVICE_CONTROL_INTERROGATE: // 4
  631 + break;
  632 +
  633 + case SERVICE_CONTROL_SHUTDOWN: // 5
  634 + // Don't waste time with reporting stop pending, just do it
  635 + QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + SERVICE_CONTROL_STOP)));
  636 + instance->condition.wait(&instance->mutex);
  637 + // status will be reported as stopped by start() when qapp::exec returns
  638 + break;
  639 +
  640 + default:
  641 + if ( code >= 128 && code <= 255 ) {
  642 + QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
  643 + instance->condition.wait(&instance->mutex);
  644 + }
  645 + break;
  646 + }
  647 +
  648 + instance->mutex.unlock();
  649 +
  650 + // Report current status
  651 + if (instance->available() && instance->status.dwCurrentState != SERVICE_STOPPED)
  652 + pSetServiceStatus(instance->serviceStatus, &instance->status);
  653 +}
  654 +
  655 +void QtServiceSysPrivate::setStatus(DWORD state)
  656 +{
  657 + if (!available())
  658 + return;
  659 + status.dwCurrentState = state;
  660 + pSetServiceStatus(serviceStatus, &status);
  661 +}
  662 +
  663 +void QtServiceSysPrivate::setServiceFlags(QtServiceBase::ServiceFlags flags)
  664 +{
  665 + if (!available())
  666 + return;
  667 + status.dwControlsAccepted = serviceFlags(flags);
  668 + pSetServiceStatus(serviceStatus, &status);
  669 +}
  670 +
  671 +DWORD QtServiceSysPrivate::serviceFlags(QtServiceBase::ServiceFlags flags) const
  672 +{
  673 + DWORD control = 0;
  674 + if (flags & QtServiceBase::CanBeSuspended)
  675 + control |= SERVICE_ACCEPT_PAUSE_CONTINUE;
  676 + if (!(flags & QtServiceBase::CannotBeStopped))
  677 + control |= SERVICE_ACCEPT_STOP;
  678 + if (flags & QtServiceBase::NeedsStopOnShutdown)
  679 + control |= SERVICE_ACCEPT_SHUTDOWN;
  680 +
  681 + return control;
  682 +}
  683 +
  684 +#include "qtservice_win.moc"
  685 +
  686 +
  687 +class HandlerThread : public QThread
  688 +{
  689 +public:
  690 + HandlerThread()
  691 + : success(true), console(false), QThread()
  692 + {}
  693 +
  694 + bool calledOk() { return success; }
  695 + bool runningAsConsole() { return console; }
  696 +
  697 +protected:
  698 + bool success, console;
  699 + void run()
  700 + {
  701 + SERVICE_TABLE_ENTRYW st [2];
  702 + st[0].lpServiceName = (wchar_t*)QtServiceBase::instance()->serviceName().utf16();
  703 + st[0].lpServiceProc = QtServiceSysPrivate::serviceMain;
  704 + st[1].lpServiceName = 0;
  705 + st[1].lpServiceProc = 0;
  706 +
  707 + success = (pStartServiceCtrlDispatcher(st) != 0); // should block
  708 +
  709 + if (!success) {
  710 + if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
  711 + // Means we're started from console, not from service mgr
  712 + // start() will ask the mgr to start another instance of us as a service instead
  713 + console = true;
  714 + }
  715 + else {
  716 + QtServiceBase::instance()->logMessage(QString("The Service failed to start [%1]").arg(qt_error_string(GetLastError())), QtServiceBase::Error);
  717 + }
  718 + QtServiceSysPrivate::instance->startSemaphore.release(); // let start() continue, since serviceMain won't be doing it
  719 + }
  720 + }
  721 +};
  722 +
  723 +/*
  724 + Ignore WM_ENDSESSION system events, since they make the Qt kernel quit
  725 +*/
  726 +
  727 +#if QT_VERSION >= 0x050000
  728 +
  729 +class QtServiceAppEventFilter : public QAbstractNativeEventFilter
  730 +{
  731 +public:
  732 + QtServiceAppEventFilter() {}
  733 + bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
  734 +};
  735 +
  736 +bool QtServiceAppEventFilter::nativeEventFilter(const QByteArray &, void *message, long *result)
  737 +{
  738 + MSG *winMessage = (MSG*)message;
  739 + if (winMessage->message == WM_ENDSESSION && (winMessage->lParam & ENDSESSION_LOGOFF)) {
  740 + *result = TRUE;
  741 + return true;
  742 + }
  743 + return false;
  744 +}
  745 +
  746 +Q_GLOBAL_STATIC(QtServiceAppEventFilter, qtServiceAppEventFilter)
  747 +
  748 +#else
  749 +
  750 +bool myEventFilter(void* message, long* result)
  751 +{
  752 + MSG* msg = reinterpret_cast<MSG*>(message);
  753 + if (!msg || (msg->message != WM_ENDSESSION) || !(msg->lParam & ENDSESSION_LOGOFF))
  754 + return QtServiceSysPrivate::nextFilter ? QtServiceSysPrivate::nextFilter(message, result) : false;
  755 +
  756 + if (QtServiceSysPrivate::nextFilter)
  757 + QtServiceSysPrivate::nextFilter(message, result);
  758 + if (result)
  759 + *result = TRUE;
  760 + return true;
  761 +}
  762 +
  763 +#endif
  764 +
  765 +/* There are three ways we can be started:
  766 +
  767 + - By a service controller (e.g. the Services control panel), with
  768 + no (service-specific) arguments. ServiceBase::exec() will then call
  769 + start() below, and the service will start.
  770 +
  771 + - From the console, but with no (service-specific) arguments. This
  772 + means we should ask a controller to start the service (i.e. another
  773 + instance of this executable), and then just terminate. We discover
  774 + this case (as different from the above) by the fact that
  775 + StartServiceCtrlDispatcher will return an error, instead of blocking.
  776 +
  777 + - From the console, with -e(xec) argument. ServiceBase::exec() will
  778 + then call ServiceBasePrivate::exec(), which calls
  779 + ServiceBasePrivate::run(), which runs the application as a normal
  780 + program.
  781 +*/
  782 +
  783 +bool QtServiceBasePrivate::start()
  784 +{
  785 + sysInit();
  786 + if (!winServiceInit())
  787 + return false;
  788 +
  789 + // Since StartServiceCtrlDispatcher() blocks waiting for service
  790 + // control events, we need to call it in another thread, so that
  791 + // the main thread can run the QApplication event loop.
  792 + HandlerThread* ht = new HandlerThread();
  793 + ht->start();
  794 +
  795 + QtServiceSysPrivate* sys = QtServiceSysPrivate::instance;
  796 +
  797 + // Wait until service args have been received by serviceMain.
  798 + // If Windows doesn't call serviceMain (or
  799 + // StartServiceControlDispatcher doesn't return an error) within
  800 + // a timeout of 20 secs, something is very wrong; give up
  801 + if (!sys->startSemaphore.tryAcquire(1, 20000))
  802 + return false;
  803 +
  804 + if (!ht->calledOk()) {
  805 + if (ht->runningAsConsole())
  806 + return controller.start(args.mid(1));
  807 + else
  808 + return false;
  809 + }
  810 +
  811 + int argc = sys->serviceArgs.size();
  812 + QVector<char *> argv(argc);
  813 + QList<QByteArray> argvData;
  814 + for (int i = 0; i < argc; ++i)
  815 + argvData.append(sys->serviceArgs.at(i).toLocal8Bit());
  816 + for (int i = 0; i < argc; ++i)
  817 + argv[i] = argvData[i].data();
  818 +
  819 + q_ptr->createApplication(argc, argv.data());
  820 + QCoreApplication *app = QCoreApplication::instance();
  821 + if (!app)
  822 + return false;
  823 +
  824 +#if QT_VERSION >= 0x050000
  825 + QAbstractEventDispatcher::instance()->installNativeEventFilter(qtServiceAppEventFilter());
  826 +#else
  827 + QtServiceSysPrivate::nextFilter = app->setEventFilter(myEventFilter);
  828 +#endif
  829 +
  830 + sys->controllerHandler = new QtServiceControllerHandler(sys);
  831 +
  832 + sys->startSemaphore2.release(); // let serviceMain continue (and end)
  833 +
  834 + sys->status.dwWin32ExitCode = q_ptr->executeApplication();
  835 + sys->setStatus(SERVICE_STOPPED);
  836 +
  837 + if (ht->isRunning())
  838 + ht->wait(1000); // let the handler thread finish
  839 + delete sys->controllerHandler;
  840 + sys->controllerHandler = 0;
  841 + if (ht->isFinished())
  842 + delete ht;
  843 + delete app;
  844 + sysCleanup();
  845 + return true;
  846 +}
  847 +
  848 +bool QtServiceBasePrivate::install(const QString &account, const QString &password)
  849 +{
  850 + bool result = false;
  851 + if (!winServiceInit())
  852 + return result;
  853 +
  854 + // Open the Service Control Manager
  855 + SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
  856 + if (hSCM) {
  857 + QString acc = account;
  858 + DWORD dwStartType = startupType == QtServiceController::AutoStartup ? SERVICE_AUTO_START : SERVICE_DEMAND_START;
  859 + DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS;
  860 + wchar_t *act = 0;
  861 + wchar_t *pwd = 0;
  862 + if (!acc.isEmpty()) {
  863 + // The act string must contain a string of the format "Domain\UserName",
  864 + // so if only a username was specified without a domain, default to the local machine domain.
  865 + if (!acc.contains(QChar('\\'))) {
  866 + acc.prepend(QLatin1String(".\\"));
  867 + }
  868 + if (!acc.endsWith(QLatin1String("\\LocalSystem")))
  869 + act = (wchar_t*)acc.utf16();
  870 + }
  871 + if (!password.isEmpty() && act) {
  872 + pwd = (wchar_t*)password.utf16();
  873 + }
  874 +
  875 + // Only set INTERACTIVE if act is LocalSystem. (and act should be 0 if it is LocalSystem).
  876 + if (!act) dwServiceType |= SERVICE_INTERACTIVE_PROCESS;
  877 +
  878 + // Create the service
  879 + SC_HANDLE hService = pCreateService(hSCM, (wchar_t *)controller.serviceName().utf16(),
  880 + (wchar_t *)controller.serviceName().utf16(),
  881 + SERVICE_ALL_ACCESS,
  882 + dwServiceType, // QObject::inherits ( const char * className ) for no inter active ????
  883 + dwStartType, SERVICE_ERROR_NORMAL, (wchar_t *)filePath().utf16(),
  884 + 0, 0, 0,
  885 + act, pwd);
  886 + if (hService) {
  887 + result = true;
  888 + if (!serviceDescription.isEmpty()) {
  889 + SERVICE_DESCRIPTION sdesc;
  890 + sdesc.lpDescription = (wchar_t *)serviceDescription.utf16();
  891 + pChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sdesc);
  892 + }
  893 + pCloseServiceHandle(hService);
  894 + }
  895 + pCloseServiceHandle(hSCM);
  896 + }
  897 + return result;
  898 +}
  899 +
  900 +QString QtServiceBasePrivate::filePath() const
  901 +{
  902 + wchar_t path[_MAX_PATH];
  903 + ::GetModuleFileNameW( 0, path, sizeof(path) );
  904 + return QString::fromUtf16((unsigned short*)path);
  905 +}
  906 +
  907 +bool QtServiceBasePrivate::sysInit()
  908 +{
  909 + sysd = new QtServiceSysPrivate();
  910 +
  911 + sysd->serviceStatus = 0;
  912 + sysd->status.dwServiceType = SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
  913 + sysd->status.dwCurrentState = SERVICE_STOPPED;
  914 + sysd->status.dwControlsAccepted = sysd->serviceFlags(serviceFlags);
  915 + sysd->status.dwWin32ExitCode = NO_ERROR;
  916 + sysd->status.dwServiceSpecificExitCode = 0;
  917 + sysd->status.dwCheckPoint = 0;
  918 + sysd->status.dwWaitHint = 0;
  919 +
  920 + return true;
  921 +}
  922 +
  923 +void QtServiceBasePrivate::sysSetPath()
  924 +{
  925 +
  926 +}
  927 +
  928 +void QtServiceBasePrivate::sysCleanup()
  929 +{
  930 + if (sysd) {
  931 + delete sysd;
  932 + sysd = 0;
  933 + }
  934 +}
  935 +
  936 +void QtServiceBase::setServiceFlags(QtServiceBase::ServiceFlags flags)
  937 +{
  938 + if (d_ptr->serviceFlags == flags)
  939 + return;
  940 + d_ptr->serviceFlags = flags;
  941 + if (d_ptr->sysd)
  942 + d_ptr->sysd->setServiceFlags(flags);
  943 +}
  944 +
  945 +
... ...
src/qtservice/src/qtunixserversocket.cpp 0 → 100644
... ... @@ -0,0 +1,92 @@
  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 <sys/types.h>
  43 +#include <sys/un.h>
  44 +#include <sys/socket.h>
  45 +#include <string.h>
  46 +#include <unistd.h>
  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 +}
... ...
src/qtservice/src/qtunixserversocket.h 0 → 100644
... ... @@ -0,0 +1,61 @@
  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 <QTcpServer>
  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
... ...
src/qtservice/src/qtunixsocket.cpp 0 → 100644
... ... @@ -0,0 +1,78 @@
  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 <sys/types.h>
  43 +#include <sys/un.h>
  44 +#include <sys/socket.h>
  45 +#include <string.h>
  46 +#include <unistd.h>
  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 +}
... ...
src/qtservice/src/qtunixsocket.h 0 → 100644
... ... @@ -0,0 +1,55 @@
  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 <QTcpSocket>
  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
... ...