#include <QtCore/QDebug>
#endif
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+# include <QAbstractNativeEventFilter>
+
+typedef bool (*QtServiceEvent)(void *message, long *result) ;
+
+class QtServiceEventFilter : public QAbstractNativeEventFilter
+{
+public:
+ QtServiceEventFilter(QtServiceEvent e) : ev(e) {}
+ virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(eventType);
+ return ev(message, result);
+ }
+private:
+ QtServiceEvent ev;
+};
+#endif
+
typedef SERVICE_STATUS_HANDLE(WINAPI*PRegisterServiceCtrlHandler)(const wchar_t*,LPHANDLER_FUNCTION);
static PRegisterServiceCtrlHandler pRegisterServiceCtrlHandler = 0;
typedef BOOL(WINAPI*PSetServiceStatus)(SERVICE_STATUS_HANDLE,LPSERVICE_STATUS);
static bool winServiceInit()
{
- if (!pOpenSCManager) {
- QLibrary lib("advapi32");
-
- // only resolve unicode versions
- RESOLVEW(RegisterServiceCtrlHandler);
- RESOLVE(SetServiceStatus);
- RESOLVEW(ChangeServiceConfig2);
- RESOLVE(CloseServiceHandle);
- RESOLVEW(CreateService);
- RESOLVEW(OpenSCManager);
- RESOLVE(DeleteService);
- RESOLVEW(OpenService);
- RESOLVE(QueryServiceStatus);
- RESOLVEW(StartServiceCtrlDispatcher);
- RESOLVEW(StartService); // need only Ansi version
- RESOLVE(ControlService);
- RESOLVE(DeregisterEventSource);
- RESOLVEW(ReportEvent);
- RESOLVEW(RegisterEventSource);
- RESOLVEW(QueryServiceConfig);
- RESOLVEW(QueryServiceConfig2);
- }
- return pOpenSCManager != 0;
+ if (!pOpenSCManager) {
+ QLibrary lib("advapi32");
+
+ // only resolve unicode versions
+ RESOLVEW(RegisterServiceCtrlHandler);
+ RESOLVE(SetServiceStatus);
+ RESOLVEW(ChangeServiceConfig2);
+ RESOLVE(CloseServiceHandle);
+ RESOLVEW(CreateService);
+ RESOLVEW(OpenSCManager);
+ RESOLVE(DeleteService);
+ RESOLVEW(OpenService);
+ RESOLVE(QueryServiceStatus);
+ RESOLVEW(StartServiceCtrlDispatcher);
+ RESOLVEW(StartService); // need only Ansi version
+ RESOLVE(ControlService);
+ RESOLVE(DeregisterEventSource);
+ RESOLVEW(ReportEvent);
+ RESOLVEW(RegisterEventSource);
+ RESOLVEW(QueryServiceConfig);
+ RESOLVEW(QueryServiceConfig2);
+ }
+ return pOpenSCManager != 0;
}
bool QtServiceController::isInstalled() const
{
- Q_D(const QtServiceController);
- bool result = false;
- if (!winServiceInit())
- return result;
-
- // Open the Service Control Manager
- SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
- if (hSCM) {
- // Try to open the service
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t*)d->serviceName.utf16(),
- SERVICE_QUERY_CONFIG);
-
- if (hService) {
- result = true;
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ Q_D(const QtServiceController);
+ bool result = false;
+ if (!winServiceInit())
+ return result;
+
+ // Open the Service Control Manager
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
+ if (hSCM) {
+ // Try to open the service
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t*)d->serviceName.utf16(),
+ SERVICE_QUERY_CONFIG);
+
+ if (hService) {
+ result = true;
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
bool QtServiceController::isRunning() const
{
- Q_D(const QtServiceController);
- bool result = false;
- if (!winServiceInit())
- return result;
-
- // Open the Service Control Manager
- SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
- if (hSCM) {
- // Try to open the service
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
- SERVICE_QUERY_STATUS);
- if (hService) {
- SERVICE_STATUS info;
- int res = pQueryServiceStatus(hService, &info);
- if (res)
- result = info.dwCurrentState != SERVICE_STOPPED;
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ Q_D(const QtServiceController);
+ bool result = false;
+ if (!winServiceInit())
+ return result;
+
+ // Open the Service Control Manager
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
+ if (hSCM) {
+ // Try to open the service
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
+ SERVICE_QUERY_STATUS);
+ if (hService) {
+ SERVICE_STATUS info;
+ int res = pQueryServiceStatus(hService, &info);
+ if (res)
+ result = info.dwCurrentState != SERVICE_STOPPED;
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
QString QtServiceController::serviceFilePath() const
{
- Q_D(const QtServiceController);
- QString result;
- if (!winServiceInit())
- return result;
-
- // Open the Service Control Manager
- SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
- if (hSCM) {
- // Try to open the service
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
- SERVICE_QUERY_CONFIG);
- if (hService) {
- DWORD sizeNeeded = 0;
- char data[8 * 1024];
- if (pQueryServiceConfig(hService, (LPQUERY_SERVICE_CONFIG)data, 8 * 1024, &sizeNeeded)) {
- LPQUERY_SERVICE_CONFIG config = (LPQUERY_SERVICE_CONFIG)data;
- result = QString::fromUtf16((const ushort*)config->lpBinaryPathName);
- }
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ Q_D(const QtServiceController);
+ QString result;
+ if (!winServiceInit())
+ return result;
+
+ // Open the Service Control Manager
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
+ if (hSCM) {
+ // Try to open the service
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
+ SERVICE_QUERY_CONFIG);
+ if (hService) {
+ DWORD sizeNeeded = 0;
+ char data[8 * 1024];
+ if (pQueryServiceConfig(hService, (LPQUERY_SERVICE_CONFIG)data, 8 * 1024, &sizeNeeded)) {
+ LPQUERY_SERVICE_CONFIG config = (LPQUERY_SERVICE_CONFIG)data;
+ result = QString::fromUtf16((const ushort*)config->lpBinaryPathName);
+ }
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
QString QtServiceController::serviceDescription() const
{
- Q_D(const QtServiceController);
- QString result;
- if (!winServiceInit())
- return result;
-
- // Open the Service Control Manager
- SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
- if (hSCM) {
- // Try to open the service
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
- SERVICE_QUERY_CONFIG);
- if (hService) {
- DWORD dwBytesNeeded;
- char data[8 * 1024];
- if (pQueryServiceConfig2(
- hService,
- SERVICE_CONFIG_DESCRIPTION,
- (unsigned char *)data,
- 8096,
- &dwBytesNeeded)) {
- LPSERVICE_DESCRIPTION desc = (LPSERVICE_DESCRIPTION)data;
- if (desc->lpDescription)
- result = QString::fromUtf16((const ushort*)desc->lpDescription);
- }
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ Q_D(const QtServiceController);
+ QString result;
+ if (!winServiceInit())
+ return result;
+
+ // Open the Service Control Manager
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
+ if (hSCM) {
+ // Try to open the service
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
+ SERVICE_QUERY_CONFIG);
+ if (hService) {
+ DWORD dwBytesNeeded;
+ char data[8 * 1024];
+ if (pQueryServiceConfig2(
+ hService,
+ SERVICE_CONFIG_DESCRIPTION,
+ (unsigned char *)data,
+ 8096,
+ &dwBytesNeeded)) {
+ LPSERVICE_DESCRIPTION desc = (LPSERVICE_DESCRIPTION)data;
+ if (desc->lpDescription)
+ result = QString::fromUtf16((const ushort*)desc->lpDescription);
+ }
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
QtServiceController::StartupType QtServiceController::startupType() const
{
- Q_D(const QtServiceController);
- StartupType result = ManualStartup;
- if (!winServiceInit())
- return result;
-
- // Open the Service Control Manager
- SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
- if (hSCM) {
- // Try to open the service
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
- SERVICE_QUERY_CONFIG);
- if (hService) {
- DWORD sizeNeeded = 0;
- char data[8 * 1024];
- if (pQueryServiceConfig(hService, (QUERY_SERVICE_CONFIG *)data, 8 * 1024, &sizeNeeded)) {
- QUERY_SERVICE_CONFIG *config = (QUERY_SERVICE_CONFIG *)data;
- result = config->dwStartType == SERVICE_DEMAND_START ? ManualStartup : AutoStartup;
- }
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ Q_D(const QtServiceController);
+ StartupType result = ManualStartup;
+ if (!winServiceInit())
+ return result;
+
+ // Open the Service Control Manager
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, 0);
+ if (hSCM) {
+ // Try to open the service
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
+ SERVICE_QUERY_CONFIG);
+ if (hService) {
+ DWORD sizeNeeded = 0;
+ char data[8 * 1024];
+ if (pQueryServiceConfig(hService, (QUERY_SERVICE_CONFIG *)data, 8 * 1024, &sizeNeeded)) {
+ QUERY_SERVICE_CONFIG *config = (QUERY_SERVICE_CONFIG *)data;
+ result = config->dwStartType == SERVICE_DEMAND_START ? ManualStartup : AutoStartup;
+ }
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
bool QtServiceController::uninstall()
{
- Q_D(QtServiceController);
- bool result = false;
- if (!winServiceInit())
- return result;
-
- // Open the Service Control Manager
- SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
- if (hSCM) {
- // Try to open the service
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(), DELETE);
- if (hService) {
- if (pDeleteService(hService))
- result = true;
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ Q_D(QtServiceController);
+ bool result = false;
+ if (!winServiceInit())
+ return result;
+
+ // Open the Service Control Manager
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+ if (hSCM) {
+ // Try to open the service
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(), DELETE);
+ if (hService) {
+ if (pDeleteService(hService))
+ result = true;
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
bool QtServiceController::start(const QStringList &args)
{
- Q_D(QtServiceController);
- bool result = false;
- if (!winServiceInit())
- return result;
-
- // Open the Service Control Manager
- SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
- if (hSCM) {
- // Try to open the service
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(), SERVICE_START);
- if (hService) {
- QVector<const wchar_t *> argv(args.size());
- for (int i = 0; i < args.size(); ++i)
- argv[i] = (const wchar_t*)args.at(i).utf16();
-
- if (pStartService(hService, args.size(), argv.data()))
- result = true;
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ Q_D(QtServiceController);
+ bool result = false;
+ if (!winServiceInit())
+ return result;
+
+ // Open the Service Control Manager
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
+ if (hSCM) {
+ // Try to open the service
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(), SERVICE_START);
+ if (hService) {
+ QVector<const wchar_t *> argv(args.size());
+ for (int i = 0; i < args.size(); ++i)
+ argv[i] = (const wchar_t*)args.at(i).utf16();
+
+ if (pStartService(hService, args.size(), argv.data()))
+ result = true;
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
bool QtServiceController::stop()
{
- Q_D(QtServiceController);
- bool result = false;
- if (!winServiceInit())
- return result;
-
- SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
- if (hSCM) {
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(), SERVICE_STOP|SERVICE_QUERY_STATUS);
- if (hService) {
- SERVICE_STATUS status;
- if (pControlService(hService, SERVICE_CONTROL_STOP, &status)) {
- bool stopped = status.dwCurrentState == SERVICE_STOPPED;
- int i = 0;
- while(!stopped && i < 10) {
- Sleep(200);
- if (!pQueryServiceStatus(hService, &status))
- break;
- stopped = status.dwCurrentState == SERVICE_STOPPED;
- ++i;
- }
- result = stopped;
- } else {
- qErrnoWarning(GetLastError(), "stopping");
- }
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ Q_D(QtServiceController);
+ bool result = false;
+ if (!winServiceInit())
+ return result;
+
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
+ if (hSCM) {
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(), SERVICE_STOP|SERVICE_QUERY_STATUS);
+ if (hService) {
+ SERVICE_STATUS status;
+ if (pControlService(hService, SERVICE_CONTROL_STOP, &status)) {
+ bool stopped = status.dwCurrentState == SERVICE_STOPPED;
+ int i = 0;
+ while(!stopped && i < 10) {
+ Sleep(200);
+ if (!pQueryServiceStatus(hService, &status))
+ break;
+ stopped = status.dwCurrentState == SERVICE_STOPPED;
+ ++i;
+ }
+ result = stopped;
+ } else {
+ qErrnoWarning(GetLastError(), "stopping");
+ }
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
bool QtServiceController::pause()
{
- Q_D(QtServiceController);
- bool result = false;
- if (!winServiceInit())
- return result;
-
- SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
- if (hSCM) {
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
- SERVICE_PAUSE_CONTINUE);
- if (hService) {
- SERVICE_STATUS status;
- if (pControlService(hService, SERVICE_CONTROL_PAUSE, &status))
- result = true;
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ Q_D(QtServiceController);
+ bool result = false;
+ if (!winServiceInit())
+ return result;
+
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
+ if (hSCM) {
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
+ SERVICE_PAUSE_CONTINUE);
+ if (hService) {
+ SERVICE_STATUS status;
+ if (pControlService(hService, SERVICE_CONTROL_PAUSE, &status))
+ result = true;
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
bool QtServiceController::resume()
{
- Q_D(QtServiceController);
- bool result = false;
- if (!winServiceInit())
- return result;
-
- SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
- if (hSCM) {
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
- SERVICE_PAUSE_CONTINUE);
- if (hService) {
- SERVICE_STATUS status;
- if (pControlService(hService, SERVICE_CONTROL_CONTINUE, &status))
- result = true;
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ Q_D(QtServiceController);
+ bool result = false;
+ if (!winServiceInit())
+ return result;
+
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
+ if (hSCM) {
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
+ SERVICE_PAUSE_CONTINUE);
+ if (hService) {
+ SERVICE_STATUS status;
+ if (pControlService(hService, SERVICE_CONTROL_CONTINUE, &status))
+ result = true;
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
bool QtServiceController::sendCommand(int code)
Q_D(QtServiceController);
bool result = false;
if (!winServiceInit())
- return result;
-
- if (code < 0 || code > 127 || !isRunning())
- return result;
-
- SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
- if (hSCM) {
- SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
- SERVICE_USER_DEFINED_CONTROL);
- if (hService) {
- SERVICE_STATUS status;
- if (pControlService(hService, 128 + code, &status))
- result = true;
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ return result;
+
+ if (code < 0 || code > 127 || !isRunning())
+ return result;
+
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_CONNECT);
+ if (hSCM) {
+ SC_HANDLE hService = pOpenService(hSCM, (wchar_t *)d->serviceName.utf16(),
+ SERVICE_USER_DEFINED_CONTROL);
+ if (hService) {
+ SERVICE_STATUS status;
+ if (pControlService(hService, 128 + code, &status))
+ result = true;
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
#if defined(QTSERVICE_DEBUG)
#endif
void QtServiceBase::logMessage(const QString &message, MessageType type,
- int id, uint category, const QByteArray &data)
+ int id, uint category, const QByteArray &data)
{
#if defined(QTSERVICE_DEBUG)
- QByteArray dbgMsg("[LOGGED ");
- switch (type) {
- case Error: dbgMsg += "Error] " ; break;
- case Warning: dbgMsg += "Warning] "; break;
- case Success: dbgMsg += "Success] "; break;
- case Information: //fall through
- default: dbgMsg += "Information] "; break;
- }
- dbgMsg += message.toAscii();
- qtServiceLogDebug((QtMsgType)-1, dbgMsg.constData());
+ QByteArray dbgMsg("[LOGGED ");
+ switch (type) {
+ case Error: dbgMsg += "Error] " ; break;
+ case Warning: dbgMsg += "Warning] "; break;
+ case Success: dbgMsg += "Success] "; break;
+ case Information: //fall through
+ default: dbgMsg += "Information] "; break;
+ }
+ dbgMsg += message.toAscii();
+ qtServiceLogDebug((QtMsgType)-1, dbgMsg.constData());
#endif
- Q_D(QtServiceBase);
- if (!winServiceInit())
- return;
- WORD wType;
- switch (type) {
- case Error: wType = EVENTLOG_ERROR_TYPE; break;
- case Warning: wType = EVENTLOG_WARNING_TYPE; break;
- case Information: wType = EVENTLOG_INFORMATION_TYPE; break;
- default: wType = EVENTLOG_SUCCESS; break;
- }
- HANDLE h = pRegisterEventSource(0, (wchar_t *)d->controller.serviceName().utf16());
- if (h) {
- const wchar_t *msg = (wchar_t*)message.utf16();
- const char *bindata = data.size() ? data.constData() : 0;
- pReportEvent(h, wType, category, id, 0, 1, data.size(),(const wchar_t **)&msg,
- const_cast<char *>(bindata));
- pDeregisterEventSource(h);
- }
+ Q_D(QtServiceBase);
+ if (!winServiceInit())
+ return;
+ WORD wType;
+ switch (type) {
+ case Error: wType = EVENTLOG_ERROR_TYPE; break;
+ case Warning: wType = EVENTLOG_WARNING_TYPE; break;
+ case Information: wType = EVENTLOG_INFORMATION_TYPE; break;
+ default: wType = EVENTLOG_SUCCESS; break;
+ }
+ HANDLE h = pRegisterEventSource(0, (wchar_t *)d->controller.serviceName().utf16());
+ if (h) {
+ const wchar_t *msg = (wchar_t*)message.utf16();
+ const char *bindata = data.size() ? data.constData() : 0;
+ pReportEvent(h, wType, category, id, 0, 1, data.size(),(const wchar_t **)&msg,
+ const_cast<char *>(bindata));
+ pDeregisterEventSource(h);
+ }
}
class QtServiceControllerHandler : public QObject
{
- Q_OBJECT
+ Q_OBJECT
public:
- QtServiceControllerHandler(QtServiceSysPrivate *sys);
+ QtServiceControllerHandler(QtServiceSysPrivate *sys);
protected:
- void customEvent(QEvent *e);
+ void customEvent(QEvent *e);
private:
- QtServiceSysPrivate *d_sys;
+ QtServiceSysPrivate *d_sys;
};
class QtServiceSysPrivate
{
public:
- enum {
- QTSERVICE_STARTUP = 256
- };
- QtServiceSysPrivate();
-
- void setStatus( DWORD dwState );
- void setServiceFlags(QtServiceBase::ServiceFlags flags);
- DWORD serviceFlags(QtServiceBase::ServiceFlags flags) const;
- inline bool available() const;
- static void WINAPI serviceMain( DWORD dwArgc, wchar_t** lpszArgv );
- static void WINAPI handler( DWORD dwOpcode );
-
- SERVICE_STATUS status;
- SERVICE_STATUS_HANDLE serviceStatus;
- QStringList serviceArgs;
-
- static QtServiceSysPrivate *instance;
- static QCoreApplication::EventFilter nextFilter;
+ enum {
+ QTSERVICE_STARTUP = 256
+ };
+ QtServiceSysPrivate();
+
+ void setStatus( DWORD dwState );
+ void setServiceFlags(QtServiceBase::ServiceFlags flags);
+ DWORD serviceFlags(QtServiceBase::ServiceFlags flags) const;
+ inline bool available() const;
+ static void WINAPI serviceMain( DWORD dwArgc, wchar_t** lpszArgv );
+ static void WINAPI handler( DWORD dwOpcode );
+
+ SERVICE_STATUS status;
+ SERVICE_STATUS_HANDLE serviceStatus;
+ QStringList serviceArgs;
+
+ static QtServiceSysPrivate *instance;
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ static QtServiceEventFilter *serviceFilter;
+#else
+ static QCoreApplication::EventFilter nextFilter;
+#endif
- QWaitCondition condition;
- QMutex mutex;
- QSemaphore startSemaphore;
- QSemaphore startSemaphore2;
+ QWaitCondition condition;
+ QMutex mutex;
+ QSemaphore startSemaphore;
+ QSemaphore startSemaphore2;
- QtServiceControllerHandler *controllerHandler;
+ QtServiceControllerHandler *controllerHandler;
- void handleCustomEvent(QEvent *e);
+ void handleCustomEvent(QEvent *e);
};
QtServiceControllerHandler::QtServiceControllerHandler(QtServiceSysPrivate *sys)
- : QObject(), d_sys(sys)
+ : QObject(), d_sys(sys)
{
}
void QtServiceControllerHandler::customEvent(QEvent *e)
{
- d_sys->handleCustomEvent(e);
+ d_sys->handleCustomEvent(e);
}
QtServiceSysPrivate *QtServiceSysPrivate::instance = 0;
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+QtServiceEventFilter *QtServiceSysPrivate::serviceFilter = 0;
+#else
QCoreApplication::EventFilter QtServiceSysPrivate::nextFilter = 0;
+#endif
QtServiceSysPrivate::QtServiceSysPrivate()
{
- instance = this;
+ instance = this;
}
inline bool QtServiceSysPrivate::available() const
{
- return 0 != pOpenSCManager;
+ return 0 != pOpenSCManager;
}
void WINAPI QtServiceSysPrivate::serviceMain(DWORD dwArgc, wchar_t** lpszArgv)
{
- if (!instance || !QtServiceBase::instance())
- return;
+ if (!instance || !QtServiceBase::instance())
+ return;
- // Windows spins off a random thread to call this function on
- // startup, so here we just signal to the QApplication event loop
- // in the main thread to go ahead with start()'ing the service.
+ // Windows spins off a random thread to call this function on
+ // startup, so here we just signal to the QApplication event loop
+ // in the main thread to go ahead with start()'ing the service.
- for (DWORD i = 0; i < dwArgc; i++)
- instance->serviceArgs.append(QString::fromUtf16((unsigned short*)lpszArgv[i]));
+ for (DWORD i = 0; i < dwArgc; i++)
+ instance->serviceArgs.append(QString::fromUtf16((unsigned short*)lpszArgv[i]));
- instance->startSemaphore.release(); // let the qapp creation start
- instance->startSemaphore2.acquire(); // wait until its done
- // Register the control request handler
- instance->serviceStatus = pRegisterServiceCtrlHandler((TCHAR*)QtServiceBase::instance()->serviceName().utf16(), handler);
+ instance->startSemaphore.release(); // let the qapp creation start
+ instance->startSemaphore2.acquire(); // wait until its done
+ // Register the control request handler
+ instance->serviceStatus = pRegisterServiceCtrlHandler((TCHAR*)QtServiceBase::instance()->serviceName().utf16(), handler);
- if (!instance->serviceStatus) // cannot happen - something is utterly wrong
- return;
+ if (!instance->serviceStatus) // cannot happen - something is utterly wrong
+ return;
- handler(QTSERVICE_STARTUP); // Signal startup to the application -
- // causes QtServiceBase::start() to be called in the main thread
+ handler(QTSERVICE_STARTUP); // Signal startup to the application -
+ // causes QtServiceBase::start() to be called in the main thread
- // The MSDN doc says that this thread should just exit - the service is
- // running in the main thread (here, via callbacks in the handler thread).
+ // The MSDN doc says that this thread should just exit - the service is
+ // running in the main thread (here, via callbacks in the handler thread).
}
// and a QMutex to synchronize.
void QtServiceSysPrivate::handleCustomEvent(QEvent *e)
{
- int code = e->type() - QEvent::User;
-
- switch(code) {
- case QTSERVICE_STARTUP: // Startup
- QtServiceBase::instance()->start();
- break;
- case SERVICE_CONTROL_STOP:
- QtServiceBase::instance()->stop();
- QCoreApplication::instance()->quit();
- break;
- case SERVICE_CONTROL_PAUSE:
- QtServiceBase::instance()->pause();
- break;
- case SERVICE_CONTROL_CONTINUE:
- QtServiceBase::instance()->resume();
- break;
- default:
+ int code = e->type() - QEvent::User;
+
+ switch(code) {
+ case QTSERVICE_STARTUP: // Startup
+ QtServiceBase::instance()->start();
+ break;
+ case SERVICE_CONTROL_STOP:
+ QtServiceBase::instance()->stop();
+ QCoreApplication::instance()->quit();
+ break;
+ case SERVICE_CONTROL_PAUSE:
+ QtServiceBase::instance()->pause();
+ break;
+ case SERVICE_CONTROL_CONTINUE:
+ QtServiceBase::instance()->resume();
+ break;
+ default:
if (code >= 128 && code <= 255)
- QtServiceBase::instance()->processCommand(code - 128);
- break;
- }
+ QtServiceBase::instance()->processCommand(code - 128);
+ break;
+ }
- mutex.lock();
- condition.wakeAll();
- mutex.unlock();
+ mutex.lock();
+ condition.wakeAll();
+ mutex.unlock();
}
void WINAPI QtServiceSysPrivate::handler( DWORD code )
{
- if (!instance)
- return;
-
- instance->mutex.lock();
- switch (code) {
- case QTSERVICE_STARTUP: // QtService startup (called from WinMain when started)
- instance->setStatus(SERVICE_START_PENDING);
- QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
- instance->condition.wait(&instance->mutex);
- instance->setStatus(SERVICE_RUNNING);
- break;
- case SERVICE_CONTROL_STOP: // 1
- instance->setStatus(SERVICE_STOP_PENDING);
- QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
- instance->condition.wait(&instance->mutex);
- // status will be reported as stopped by start() when qapp::exec returns
- break;
-
- case SERVICE_CONTROL_PAUSE: // 2
- instance->setStatus(SERVICE_PAUSE_PENDING);
- QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
- instance->condition.wait(&instance->mutex);
- instance->setStatus(SERVICE_PAUSED);
- break;
-
- case SERVICE_CONTROL_CONTINUE: // 3
- instance->setStatus(SERVICE_CONTINUE_PENDING);
- QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
- instance->condition.wait(&instance->mutex);
- instance->setStatus(SERVICE_RUNNING);
- break;
-
- case SERVICE_CONTROL_INTERROGATE: // 4
- break;
-
- case SERVICE_CONTROL_SHUTDOWN: // 5
- // Don't waste time with reporting stop pending, just do it
- QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + SERVICE_CONTROL_STOP)));
- instance->condition.wait(&instance->mutex);
- // status will be reported as stopped by start() when qapp::exec returns
- break;
-
- default:
- if ( code >= 128 && code <= 255 ) {
- QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
- instance->condition.wait(&instance->mutex);
- }
- break;
- }
-
- instance->mutex.unlock();
-
- // Report current status
- if (instance->available() && instance->status.dwCurrentState != SERVICE_STOPPED)
- pSetServiceStatus(instance->serviceStatus, &instance->status);
+ if (!instance)
+ return;
+
+ instance->mutex.lock();
+ switch (code) {
+ case QTSERVICE_STARTUP: // QtService startup (called from WinMain when started)
+ instance->setStatus(SERVICE_START_PENDING);
+ QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
+ instance->condition.wait(&instance->mutex);
+ instance->setStatus(SERVICE_RUNNING);
+ break;
+ case SERVICE_CONTROL_STOP: // 1
+ instance->setStatus(SERVICE_STOP_PENDING);
+ QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
+ instance->condition.wait(&instance->mutex);
+ // status will be reported as stopped by start() when qapp::exec returns
+ break;
+
+ case SERVICE_CONTROL_PAUSE: // 2
+ instance->setStatus(SERVICE_PAUSE_PENDING);
+ QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
+ instance->condition.wait(&instance->mutex);
+ instance->setStatus(SERVICE_PAUSED);
+ break;
+
+ case SERVICE_CONTROL_CONTINUE: // 3
+ instance->setStatus(SERVICE_CONTINUE_PENDING);
+ QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
+ instance->condition.wait(&instance->mutex);
+ instance->setStatus(SERVICE_RUNNING);
+ break;
+
+ case SERVICE_CONTROL_INTERROGATE: // 4
+ break;
+
+ case SERVICE_CONTROL_SHUTDOWN: // 5
+ // Don't waste time with reporting stop pending, just do it
+ QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + SERVICE_CONTROL_STOP)));
+ instance->condition.wait(&instance->mutex);
+ // status will be reported as stopped by start() when qapp::exec returns
+ break;
+
+ default:
+ if ( code >= 128 && code <= 255 ) {
+ QCoreApplication::postEvent(instance->controllerHandler, new QEvent(QEvent::Type(QEvent::User + code)));
+ instance->condition.wait(&instance->mutex);
+ }
+ break;
+ }
+
+ instance->mutex.unlock();
+
+ // Report current status
+ if (instance->available() && instance->status.dwCurrentState != SERVICE_STOPPED)
+ pSetServiceStatus(instance->serviceStatus, &instance->status);
}
void QtServiceSysPrivate::setStatus(DWORD state)
{
- if (!available())
+ if (!available())
return;
- status.dwCurrentState = state;
- pSetServiceStatus(serviceStatus, &status);
+ status.dwCurrentState = state;
+ pSetServiceStatus(serviceStatus, &status);
}
void QtServiceSysPrivate::setServiceFlags(QtServiceBase::ServiceFlags flags)
{
- if (!available())
- return;
- status.dwControlsAccepted = serviceFlags(flags);
- pSetServiceStatus(serviceStatus, &status);
+ if (!available())
+ return;
+ status.dwControlsAccepted = serviceFlags(flags);
+ pSetServiceStatus(serviceStatus, &status);
}
DWORD QtServiceSysPrivate::serviceFlags(QtServiceBase::ServiceFlags flags) const
{
- DWORD control = 0;
- if (flags & QtServiceBase::CanBeSuspended)
- control |= SERVICE_ACCEPT_PAUSE_CONTINUE;
- if (!(flags & QtServiceBase::CannotBeStopped))
- control |= SERVICE_ACCEPT_STOP;
- if (flags & QtServiceBase::NeedsStopOnShutdown)
- control |= SERVICE_ACCEPT_SHUTDOWN;
+ DWORD control = 0;
+ if (flags & QtServiceBase::CanBeSuspended)
+ control |= SERVICE_ACCEPT_PAUSE_CONTINUE;
+ if (!(flags & QtServiceBase::CannotBeStopped))
+ control |= SERVICE_ACCEPT_STOP;
+ if (flags & QtServiceBase::NeedsStopOnShutdown)
+ control |= SERVICE_ACCEPT_SHUTDOWN;
- return control;
+ return control;
}
#include "qtservice_win.moc"
class HandlerThread : public QThread
{
public:
- HandlerThread()
- : success(true), console(false), QThread()
- {}
+ HandlerThread()
+ : success(true), console(false), QThread()
+ {}
- bool calledOk() { return success; }
- bool runningAsConsole() { return console; }
+ bool calledOk() { return success; }
+ bool runningAsConsole() { return console; }
protected:
- bool success, console;
- void run()
- {
- SERVICE_TABLE_ENTRYW st [2];
- st[0].lpServiceName = (wchar_t*)QtServiceBase::instance()->serviceName().utf16();
- st[0].lpServiceProc = QtServiceSysPrivate::serviceMain;
- st[1].lpServiceName = 0;
- st[1].lpServiceProc = 0;
-
- success = (pStartServiceCtrlDispatcher(st) != 0); // should block
-
- if (!success) {
- if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
- // Means we're started from console, not from service mgr
- // start() will ask the mgr to start another instance of us as a service instead
- console = true;
- }
- else {
- QtServiceBase::instance()->logMessage(QString("The Service failed to start [%1]").arg(qt_error_string(GetLastError())), QtServiceBase::Error);
- }
- QtServiceSysPrivate::instance->startSemaphore.release(); // let start() continue, since serviceMain won't be doing it
- }
- }
+ bool success, console;
+ void run()
+ {
+ SERVICE_TABLE_ENTRYW st [2];
+ st[0].lpServiceName = (wchar_t*)QtServiceBase::instance()->serviceName().utf16();
+ st[0].lpServiceProc = QtServiceSysPrivate::serviceMain;
+ st[1].lpServiceName = 0;
+ st[1].lpServiceProc = 0;
+
+ success = (pStartServiceCtrlDispatcher(st) != 0); // should block
+
+ if (!success) {
+ if (GetLastError() == ERROR_FAILED_SERVICE_CONTROLLER_CONNECT) {
+ // Means we're started from console, not from service mgr
+ // start() will ask the mgr to start another instance of us as a service instead
+ console = true;
+ }
+ else {
+ QtServiceBase::instance()->logMessage(QString("The Service failed to start [%1]").arg(qt_error_string(GetLastError())), QtServiceBase::Error);
+ }
+ QtServiceSysPrivate::instance->startSemaphore.release(); // let start() continue, since serviceMain won't be doing it
+ }
+ }
};
/*
*/
bool myEventFilter(void* message, long* result)
{
- MSG* msg = reinterpret_cast<MSG*>(message);
- if (!msg || (msg->message != WM_ENDSESSION) || !(msg->lParam & ENDSESSION_LOGOFF))
- return QtServiceSysPrivate::nextFilter ? QtServiceSysPrivate::nextFilter(message, result) : false;
+ MSG* msg = reinterpret_cast<MSG*>(message);
- if (QtServiceSysPrivate::nextFilter)
- QtServiceSysPrivate::nextFilter(message, result);
- if (result)
- *result = TRUE;
- return true;
+ if (!msg || (msg->message != WM_ENDSESSION) || !(msg->lParam & ENDSESSION_LOGOFF))
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ return false;
+#else
+ return QtServiceSysPrivate::nextFilter ? QtServiceSysPrivate::nextFilter(message, result) : false;
+
+ if (QtServiceSysPrivate::nextFilter)
+ QtServiceSysPrivate::nextFilter(message, result);
+#endif
+ if (result)
+ *result = TRUE;
+ return true;
}
/* There are three ways we can be started:
ServiceBasePrivate::run(), which runs the application as a normal
program.
*/
-
bool QtServiceBasePrivate::start()
{
- sysInit();
- if (!winServiceInit())
- return false;
-
- // Since StartServiceCtrlDispatcher() blocks waiting for service
- // control events, we need to call it in another thread, so that
- // the main thread can run the QApplication event loop.
- HandlerThread* ht = new HandlerThread();
- ht->start();
-
- QtServiceSysPrivate* sys = QtServiceSysPrivate::instance;
-
- // Wait until service args have been received by serviceMain.
- // If Windows doesn't call serviceMain (or
- // StartServiceControlDispatcher doesn't return an error) within
- // a timeout of 20 secs, something is very wrong; give up
- if (!sys->startSemaphore.tryAcquire(1, 20000))
- return false;
-
- if (!ht->calledOk()) {
- if (ht->runningAsConsole())
- return controller.start(args.mid(1));
- else
- return false;
- }
-
- int argc = sys->serviceArgs.size();
- QVector<char *> argv(argc);
- QList<QByteArray> argvData;
- for (int i = 0; i < argc; ++i)
- argvData.append(sys->serviceArgs.at(i).toLocal8Bit());
- for (int i = 0; i < argc; ++i)
- argv[i] = argvData[i].data();
-
- q_ptr->createApplication(argc, argv.data());
- QCoreApplication *app = QCoreApplication::instance();
- if (!app)
- return false;
- QtServiceSysPrivate::nextFilter = app->setEventFilter(myEventFilter);
-
- sys->controllerHandler = new QtServiceControllerHandler(sys);
-
- sys->startSemaphore2.release(); // let serviceMain continue (and end)
-
- sys->status.dwWin32ExitCode = q_ptr->executeApplication();
- sys->setStatus(SERVICE_STOPPED);
-
- if (ht->isRunning())
- ht->wait(1000); // let the handler thread finish
- delete sys->controllerHandler;
- sys->controllerHandler = 0;
- if (ht->isFinished())
- delete ht;
- delete app;
- sysCleanup();
- return true;
+ sysInit();
+ if (!winServiceInit())
+ return false;
+
+ // Since StartServiceCtrlDispatcher() blocks waiting for service
+ // control events, we need to call it in another thread, so that
+ // the main thread can run the QApplication event loop.
+ HandlerThread* ht = new HandlerThread();
+ ht->start();
+
+ QtServiceSysPrivate* sys = QtServiceSysPrivate::instance;
+
+ // Wait until service args have been received by serviceMain.
+ // If Windows doesn't call serviceMain (or
+ // StartServiceControlDispatcher doesn't return an error) within
+ // a timeout of 20 secs, something is very wrong; give up
+ if (!sys->startSemaphore.tryAcquire(1, 20000))
+ return false;
+
+ if (!ht->calledOk()) {
+ if (ht->runningAsConsole())
+ return controller.start(args.mid(1));
+ else
+ return false;
+ }
+
+ int argc = sys->serviceArgs.size();
+ QVector<char *> argv(argc);
+ QList<QByteArray> argvData;
+ for (int i = 0; i < argc; ++i)
+ argvData.append(sys->serviceArgs.at(i).toLocal8Bit());
+ for (int i = 0; i < argc; ++i)
+ argv[i] = argvData[i].data();
+
+ q_ptr->createApplication(argc, argv.data());
+ QCoreApplication *app = QCoreApplication::instance();
+ if (!app)
+ return false;
+#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
+ if (!QtServiceSysPrivate::serviceFilter)
+ {
+ QtServiceSysPrivate::serviceFilter = new QtServiceEventFilter(myEventFilter);
+ app->installNativeEventFilter(QtServiceSysPrivate::serviceFilter);
+ }
+#else
+ QtServiceSysPrivate::nextFilter = app->setEventFilter(myEventFilter);
+#endif
+ sys->controllerHandler = new QtServiceControllerHandler(sys);
+
+ sys->startSemaphore2.release(); // let serviceMain continue (and end)
+
+ sys->status.dwWin32ExitCode = q_ptr->executeApplication();
+ sys->setStatus(SERVICE_STOPPED);
+
+ if (ht->isRunning())
+ ht->wait(1000); // let the handler thread finish
+ delete sys->controllerHandler;
+ sys->controllerHandler = 0;
+ if (ht->isFinished())
+ delete ht;
+ delete app;
+ sysCleanup();
+ return true;
}
bool QtServiceBasePrivate::install(const QString &account, const QString &password)
{
- bool result = false;
- if (!winServiceInit())
- return result;
-
- // Open the Service Control Manager
- SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
- if (hSCM) {
- QString acc = account;
- DWORD dwStartType = startupType == QtServiceController::AutoStartup ? SERVICE_AUTO_START : SERVICE_DEMAND_START;
- DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- wchar_t *act = 0;
- wchar_t *pwd = 0;
- if (!acc.isEmpty()) {
- // The act string must contain a string of the format "Domain\UserName",
- // so if only a username was specified without a domain, default to the local machine domain.
- if (!acc.contains(QChar('\\'))) {
- acc.prepend(QLatin1String(".\\"));
- }
- if (!acc.endsWith(QLatin1String("\\LocalSystem")))
- act = (wchar_t*)acc.utf16();
- }
- if (!password.isEmpty() && act) {
- pwd = (wchar_t*)password.utf16();
- }
-
- // Only set INTERACTIVE if act is LocalSystem. (and act should be 0 if it is LocalSystem).
- if (!act) dwServiceType |= SERVICE_INTERACTIVE_PROCESS;
-
- // Create the service
- SC_HANDLE hService = pCreateService(hSCM, (wchar_t *)controller.serviceName().utf16(),
- (wchar_t *)controller.serviceName().utf16(),
- SERVICE_ALL_ACCESS,
- dwServiceType, // QObject::inherits ( const char * className ) for no inter active ????
- dwStartType, SERVICE_ERROR_NORMAL, (wchar_t *)filePath().utf16(),
- 0, 0, 0,
- act, pwd);
- if (hService) {
- result = true;
- if (!serviceDescription.isEmpty()) {
- SERVICE_DESCRIPTION sdesc;
- sdesc.lpDescription = (wchar_t *)serviceDescription.utf16();
- pChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sdesc);
- }
- pCloseServiceHandle(hService);
- }
- pCloseServiceHandle(hSCM);
- }
- return result;
+ bool result = false;
+ if (!winServiceInit())
+ return result;
+
+ // Open the Service Control Manager
+ SC_HANDLE hSCM = pOpenSCManager(0, 0, SC_MANAGER_ALL_ACCESS);
+ if (hSCM) {
+ QString acc = account;
+ DWORD dwStartType = startupType == QtServiceController::AutoStartup ? SERVICE_AUTO_START : SERVICE_DEMAND_START;
+ DWORD dwServiceType = SERVICE_WIN32_OWN_PROCESS;
+ wchar_t *act = 0;
+ wchar_t *pwd = 0;
+ if (!acc.isEmpty()) {
+ // The act string must contain a string of the format "Domain\UserName",
+ // so if only a username was specified without a domain, default to the local machine domain.
+ if (!acc.contains(QChar('\\'))) {
+ acc.prepend(QLatin1String(".\\"));
+ }
+ if (!acc.endsWith(QLatin1String("\\LocalSystem")))
+ act = (wchar_t*)acc.utf16();
+ }
+ if (!password.isEmpty() && act) {
+ pwd = (wchar_t*)password.utf16();
+ }
+
+ // Only set INTERACTIVE if act is LocalSystem. (and act should be 0 if it is LocalSystem).
+ if (!act) dwServiceType |= SERVICE_INTERACTIVE_PROCESS;
+
+ // Create the service
+ SC_HANDLE hService = pCreateService(hSCM, (wchar_t *)controller.serviceName().utf16(),
+ (wchar_t *)controller.serviceName().utf16(),
+ SERVICE_ALL_ACCESS,
+ dwServiceType, // QObject::inherits ( const char * className ) for no inter active ????
+ dwStartType, SERVICE_ERROR_NORMAL, (wchar_t *)filePath().utf16(),
+ 0, 0, 0,
+ act, pwd);
+ if (hService) {
+ result = true;
+ if (!serviceDescription.isEmpty()) {
+ SERVICE_DESCRIPTION sdesc;
+ sdesc.lpDescription = (wchar_t *)serviceDescription.utf16();
+ pChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sdesc);
+ }
+ pCloseServiceHandle(hService);
+ }
+ pCloseServiceHandle(hSCM);
+ }
+ return result;
}
QString QtServiceBasePrivate::filePath() const
{
- wchar_t path[_MAX_PATH];
- ::GetModuleFileNameW( 0, path, sizeof(path) );
- return QString::fromUtf16((unsigned short*)path);
+ wchar_t path[_MAX_PATH];
+ ::GetModuleFileNameW( 0, path, sizeof(path) );
+ return QString::fromUtf16((unsigned short*)path);
}
bool QtServiceBasePrivate::sysInit()
{
- sysd = new QtServiceSysPrivate();
+ sysd = new QtServiceSysPrivate();
- sysd->serviceStatus = 0;
- sysd->status.dwServiceType = SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
- sysd->status.dwCurrentState = SERVICE_STOPPED;
- sysd->status.dwControlsAccepted = sysd->serviceFlags(serviceFlags);
- sysd->status.dwWin32ExitCode = NO_ERROR;
- sysd->status.dwServiceSpecificExitCode = 0;
- sysd->status.dwCheckPoint = 0;
- sysd->status.dwWaitHint = 0;
+ sysd->serviceStatus = 0;
+ sysd->status.dwServiceType = SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
+ sysd->status.dwCurrentState = SERVICE_STOPPED;
+ sysd->status.dwControlsAccepted = sysd->serviceFlags(serviceFlags);
+ sysd->status.dwWin32ExitCode = NO_ERROR;
+ sysd->status.dwServiceSpecificExitCode = 0;
+ sysd->status.dwCheckPoint = 0;
+ sysd->status.dwWaitHint = 0;
- return true;
+ return true;
}
void QtServiceBasePrivate::sysSetPath()
void QtServiceBasePrivate::sysCleanup()
{
- if (sysd) {
- delete sysd;
- sysd = 0;
- }
+ if (sysd) {
+ delete sysd;
+ sysd = 0;
+ }
}
void QtServiceBase::setServiceFlags(QtServiceBase::ServiceFlags flags)
{
- if (d_ptr->serviceFlags == flags)
- return;
- d_ptr->serviceFlags = flags;
- if (d_ptr->sysd)
- d_ptr->sysd->setServiceFlags(flags);
+ if (d_ptr->serviceFlags == flags)
+ return;
+ d_ptr->serviceFlags = flags;
+ if (d_ptr->sysd)
+ d_ptr->sysd->setServiceFlags(flags);
}