将qt程序注册成服务
1、qt服务模块管理下载
qt-solutions
2、QtService项目
2.1、将qtservice拷贝到项目代码路径
2.2、实现服务管理
PS:响应服务的启停
CustomService.h
#include <QCoreApplication>
#include "qtservice.h"
class CustomService : public QtService<QCoreApplication>
{
public:
CustomService(int argc, char **argv);
protected:
void start();
void pause();
void resume();
void stop();
};
CustomService.cpp
#include "CustomService.h"
#include "ServiceHandle.h"
CustomService::CustomService(int argc, char **argv)
: QtService<QCoreApplication>(argc, argv, "Custom Qt Server")
{
setServiceDescription("Custom Qt Server");
setServiceFlags(QtServiceBase::CanBeSuspended);
}
void CustomService::start()
{
QCoreApplication *app = application();
SERVER_CTRL_INST.start();
}
void CustomService::pause()
{
SERVER_CTRL_INST.pause();
}
void CustomService::resume()
{
SERVER_CTRL_INST.resume();
}
void CustomService::stop()
{
SERVER_CTRL_INST.stop();
}
2.3、服务内部程序实现
ServiceHandle.h
#pragma once
#include "ThreadObject.h"
#define SERVER_CTRL_INST ServiceHandle::Instance()
class ServiceHandle
{
const std::string kProcessName = "QtService.exe";
public:
static ServiceHandle& Instance()
{
static ServiceHandle g_inst;
return g_inst;
}
protected:
ServiceHandle();
~ServiceHandle();
public:
void InstallService(const std::string& strServiceName = "");
void StartService(const std::string& strServiceName);
void StopService(const std::string& strServiceName);
void UninstallService(const std::string& strServiceName);
void start();
void pause();
void resume();
void stop();
private:
void do_work();
private:
Utils::ThreadObject m_objWork;
};
ServiceHandle.cpp
#include "ServiceHandle.h"
#include <fstream>
#include <QProcess>
#include <iostream>
#include <direct.h>
#include "Command.h"
static int64_t g_nCnt =0;
ServiceHandle::ServiceHandle()
{
}
ServiceHandle::~ServiceHandle()
{
}
void ServiceHandle::InstallService(const std::string& strServiceName/* = ""*/)
{
char szPath[260] = { 0 };
getcwd(szPath, 260);
std::string strPath(szPath);
strPath = strPath + "/" + kProcessName;
std::cout << "Exe path: " << szPath << "\n";
std::string strName = strServiceName.empty()? "CustomService": strServiceName;
std::string strCmd = "sc create " + strName + " binpath=" + strPath;
std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
std::cout << strResponse;
// start service
StartService(strName);
}
void ServiceHandle::StartService(const std::string& strServiceName)
{
std::string strCmd = "net start " + strServiceName;
std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
std::cout << strResponse;
}
void ServiceHandle::StopService(const std::string& strServiceName)
{
std::string strCmd = "net stop " + strServiceName;
std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
std::cout << strResponse;
}
void ServiceHandle::UninstallService(const std::string& strServiceName)
{
StopService(strServiceName);
std::string strCmd = "sc delete " + strServiceName;
std::string strResponse = Utils::CommandHelper::ExecCommand(strCmd);
std::cout << strResponse;
}
void ServiceHandle::start()
{
g_nCnt = 0;
m_objWork.Start(std::bind(&ServiceHandle::do_work, &SERVER_CTRL_INST), 2000);
}
void ServiceHandle::pause()
{
stop();
}
void ServiceHandle::resume()
{
start();
}
void ServiceHandle::stop()
{
m_objWork.Stop();
}
void ServiceHandle::do_work()
{
std::fstream fout("C:\\ProgramData\\CustomService.log", std::ios::out | std::ios::app);
if(fout.is_open()) {
fout << "Server do work: " << ++g_nCnt << "\n";
fout.close();
}
}
2.4、服务本身支持指令操作
PS:安装、卸载、启停以及常规启动(非服务)
main.cpp
#include <QApplication>
#include <iostream>
#include <string>
#include <map>
#include "CustomService.h"
#include "ServiceHandle.h"
enum ServiceCmdType
{
kServiceCmdTypeUnknown = -1,
kServiceCmdTypeHelp,
kServiceCmdTypeCommon,
kServiceCmdTypeInstall,
kServiceCmdTypeUninstall,
kServiceCmdTypeStart,
kServiceCmdTypeStop
};
std::map<std::string, ServiceCmdType> mapCmd
{
{ "help", kServiceCmdTypeHelp },
{ "common", kServiceCmdTypeCommon },
{ "install", kServiceCmdTypeInstall },
{ "uninstall", kServiceCmdTypeUninstall },
{ "start", kServiceCmdTypeStart },
{ "stop", kServiceCmdTypeStop }
};
void Usage()
{
std::cout << "Usage: QtService [command] [option1] [option2]\n";
std::cout << "command and options:\n";
std::cout << "\tinstall [service name]: install service, <service name> is optional, default is \"Custom Qt Server\" \n";
std::cout << "\tstop [service name]: stop service\n";
std::cout << "\tstart [service name]: start service\n";
std::cout << "\tuninstall [service name]: uninstall service\n";
std::cout << "\tcommon: start process in common mode\n";
std::cout << "\thelp: show usage\n";
}
bool CheckValidCmd(const std::string& strCmd, ServiceCmdType& nCmd)
{
bool bValid = false;
auto itFind = mapCmd.find(strCmd);
if(itFind != mapCmd.end()) {
bValid = true;
nCmd = itFind->second;
}
return bValid;
}
// install/uninstall/start/stop service via inner action
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
if(argc > 1) {
int nIndex = 0;
std::string strCmd = argv[++nIndex];
ServiceCmdType nCmdType = kServiceCmdTypeUnknown;
if(!CheckValidCmd(strCmd, nCmdType) || kServiceCmdTypeHelp == nCmdType) {
Usage();
return 0;
}
if(kServiceCmdTypeCommon == nCmdType) {
SERVER_CTRL_INST.start();
auto nCode = a.exec();
SERVER_CTRL_INST.stop();
return nCode;
}
if(argc < 3) {
Usage();
return 0;
}
std::string strServiceName = argv[++nIndex];
switch(nCmdType) {
case kServiceCmdTypeInstall: {
SERVER_CTRL_INST.InstallService(strServiceName);
break;
}
case kServiceCmdTypeUninstall: {
SERVER_CTRL_INST.UninstallService(strServiceName);
break;
}
case kServiceCmdTypeStart: {
SERVER_CTRL_INST.StartService(strServiceName);
break;
}
case kServiceCmdTypeStop: {
SERVER_CTRL_INST.StopService(strServiceName);
break;
}
default:
break;
}
return 0;
}
// start exe with service(default)
CustomService service(argc, argv);
return service.exec();
}
PS:
1、qt.pro里增加CONFIG+=console,这样控制台有数据输出
2、unix下注册服务,修改对应注册服务命令即可
3、服务注册原理,外层一个壳子,响应服务操作,然后再执行对应逻辑
源代码下载