PDA

View Full Version : Problems starting a QtService using QtServiceController



Stiander
9th August 2010, 08:16
Hi,

I have a QtServiceController related problem. I have made a service derived from QtService. The service functions as it should, and will install and run from a commandline (as Administrator) using the -i and -s arguments. The problem arises when I try to control the service from a separate Qt GUI application using the QtServiceController. I can successfully install the service, but it will not start. I have tried to run a release compiled executable of the GUI app as administrator, that didn't work either. This code reproduces the problem on my computer:

serviceTemplate.h :


#ifndef SERVICE_TEMPLATE_H
#define SERVICE_TEMPLATE_H
#include <QtServiceBase>

// definition of the service class
class CService : public QtService<QCoreApplication>
{
public:
CService(int argc, char **argv);
~CService(){};

protected:
void start();
void stop(){};
void pause(){};
void resume(){};
void processCommand(int code){};

private:

};
#endif

serviceTemplate.cpp :


#include "serviceTemplate.h"

CService::CService(int argc, char **argv)
: QtService<QCoreApplication>(argc, argv, "Qt Service")
{
setServiceDescription("A dummy Qt Service");
setServiceFlags(QtServiceBase::CanBeSuspended);
}

// this service does nothing
void CService::start()
{
QCoreApplication *app = application();
while(1){ // Do nothing }
}

relevant code from the GUI app :


// install service
bool ires = false;
QString servicePath = installPath + "\\service\\backupservice.exe"; // serviceTemplate.exe
serviceController = new QtServiceController(servicePath);
if(!serviceController->isInstalled())
{
log->append("\n" + QDateTime::currentDateTime().toString() +
"\n" + "Service not installed, installing...");
if((ires = serviceController->install(servicePath)) == false)
{
log->append("\n" + QDateTime::currentDateTime().toString() +
"\n" + "Error installing service, try running application as Administrator ");
MenuTab->setCurrentWidget(log);
}
}
bool startOK = serviceController->start();
bool isRunning = serviceController->isRunning();
if(isRunning)
{
log->append("\n" + QDateTime::currentDateTime().toString() +
"\n" + "Service is running");
}
else
{
// ends up here always.. why???
log->append("\n" + QDateTime::currentDateTime().toString() +
"\n" + "Could not start service, try running application as Administrator");
MenuTab->setCurrentWidget(log);
}

I migth also add that the service controller does not report the correct install-status of the service, it will always report "not installed" e.g. serviceController->isInstalled() = false, even though it is installed (confirmed with task manager). So the only thing that I can make it to do correctly, is installing the service.

Are there any known circumstances in which the service controller can't start a service, when the service can be started manually? Any help would be greatly appreciated, I've been struggling with this for some days now.

OS : Windows 7, 64
Qt : 4.5.2

Stiander
13th August 2010, 10:34
Problem remains unsolved. Noone seems to want to touch it. Please reply here if one or more of the following is valid:
* you have the same problem, and you cannot solve it either
* you had the same problem, but you solved it
* you see whats wrong with the code
* you think the code looks ok, "there must be something else"
* you could perhaps see what's wrong, but you need more information

have a good weekend everyone! ;)

granan
28th September 2010, 00:17
I have similar problem as You Stiander. I use Qt 4.7 and it doesn't see QtServiceController class. I have not found in doc on qt.nokia.com informations about this QtService module in Qt 4.7. It means that it is not support now? So how create program as service and control its cycle from Qt level?

seven7
10th May 2011, 10:54
Your CService::start() function shouldn´t be blocking. It is not supposed to be the service´s main function (it took me some time to figure that out...). Using these classes there is no main function. You just get an event loop which you start in your programs main() function using myservice.exec().

To implement your functionality you have to use an event driven approach (signals and slots). Look at the following example. It writes once a second a string to your applications event log.



#ifndef SVCMAIN_H
#define SVCMAIN_H

#include <QObject>

class SvcMain : public QObject
{
Q_OBJECT
public:
explicit SvcMain(QObject *parent = 0);

signals:

public slots:
void handleTimerEvent();
};

#endif // SVCMAIN_H


The constructor creates a periodic timer:



#include "svcmain.h"
#include <QTimer>
#include "qtservice/qtservice.h"

SvcMain::SvcMain(QObject *parent) :
QObject(parent)
{
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(handleTimerEvent()));
timer->start(1000);
}

void SvcMain::handleTimerEvent()
{
QtServiceBase::instance()->logMessage(QString("handleTimerEvent"), QtServiceBase::Information );
}


Your start() function should look like this:



void CService::start()
{
svcmain = new SvcMain();
}


svcmain is a private member variable:



private:
SvcMain* svcmain;


Look at the examples on how to implement the remaining functions (stop/resume/...).
Hope this helps.

Sebastian