将qt程序注册成服务

news2024/12/23 22:07:23

将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、服务注册原理,外层一个壳子,响应服务操作,然后再执行对应逻辑
源代码下载

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1327323.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React网页转换为pdf并下载|使用jspdf html2canvas

checkout 分支后突然报错&#xff0c;提示&#xff1a; Cant resolve jspdf in ... Cant resolve html2canvas in ... 解决方法很简单&#xff0c;重新 yarn install 就好了&#xff0c;至于为什么&#xff0c;我暂时也不知道&#xff0c;总之解决了。 思路来源&#xff1a; 先…

opencv静态链接error LNK2019

opencv 3.1.0 静态库&#xff0c;包括以下文件 只链接opencv_world310d.lib&#xff0c;报错 opencv_world310d.lib(matrix.obj) : error LNK2019: 无法解析的外部符号 _ippicvsFlip_16u_I8&#xff0c;该符号在函数 "enum IppStatus (__stdcall*__cdecl cv::getFlipFu…

安全狗云原生安全-云甲·云原生容器安全管理系统

随着云计算的快速发展&#xff0c;容器技术逐渐成为主流。然而&#xff0c;随着容器的普及&#xff0c;安全问题也日益突出。为了解决这一问题&#xff0c;安全狗推出了云原生容器安全管理系统——云甲。 云甲是安全狗云原生安全的重要组成部分&#xff0c;它采用了先进的云原生…

深入了解Spring MVC工作流程

目录 1. MVC架构简介 2. Spring MVC的工作流程 2.1. 客户端请求的处理 2.2. 视图解析和渲染 2.3. 响应生成与返回 3. Spring MVC的关键组件 3.1. DispatcherServlet 3.2. HandlerMapping 3.3. Controller 3.4. ViewResolver 4. 结论 Spring MVC&#xff08;Model-Vi…

【Midjourney】Midjourney根据prompt提示词生成黑白色图片

目录 &#x1f347;&#x1f347;Midjourney是什么&#xff1f; &#x1f349;&#x1f349;Midjourney怎么用&#xff1f; &#x1f514;&#x1f514;提示词格式 &#x1f34b;&#x1f34b;应用示例——“秘密花园”式涂色书配图生成 &#x1f34c;&#x1f34c;例子1…

浅述无人机技术在地质灾害应急救援场景中的应用

12月18日23时&#xff0c;甘肃临夏州积石山县发生6.2级地震&#xff0c;震源深度10千米&#xff0c;灾区电力、通信受到影响。地震发生后&#xff0c;无人机技术也火速应用在灾区的应急抢险中。目前&#xff0c;根据受灾地区实际情况&#xff0c;翼龙-2H应急救灾型无人机已出动…

vivado生成时钟分析

生成的时钟 本节讨论生成的时钟&#xff0c;包括&#xff1a; •关于生成的时钟 •用户定义的生成时钟 •自动衍生时钟 •自动衍生时钟 关于生成的时钟 生成的时钟在设计内部由称为时钟修改块&#xff08;用于例如MMCM&#xff09;&#xff0c;或者通过一些用户逻辑。生…

应用 Strangler 模式将遗留系统分解为微服务

许多来源在一般情况下提供了微服务的解释&#xff0c;但缺乏特定领域的示例。新来者或不确定从哪里开始的人可能会发现掌握如何将遗留系统过渡到微服务架构具有挑战性。本指南主要面向那些正在努力启动迁移工作的个人&#xff0c;它提供了特定于业务的示例来帮助理解该过程。 …

EasyExcel使用: RGB字体,RGB背景颜色,fillForegroundColor颜色对照表

EasyExcel使用: RGB字体&#xff0c;RGB背景颜色&#xff0c;fillForegroundColor颜色对照表 使用EasyExcel导出表格可能会对字体颜色和单元格背景颜色进行自定义的修改。 可以自定义字体颜色或者每个单元格的颜色 要想自定义颜色&#xff0c;需要重写CellWriteHandler接口&am…

用友U8+CRM help2 任意文件读取漏洞复现

0x01 产品简介 用友U8 CRM客户关系管理系统是一款专业的企业级CRM软件&#xff0c;旨在帮助企业高效管理客户关系、提升销售业绩和提供优质的客户服务。 0x02 漏洞概述 用友 U8 CRM客户关系管理系统 help2接口处存在任意文件读取漏洞&#xff0c;攻击者通过漏洞可以获取到服…

【PyTorch】代码学习

文章目录 直接定义nn.Sequential(), 然后append(),最后直接net(),少写很多forward&#xff0c;适合直连式网络 直接定义nn.Sequential(), 然后append(),最后直接net(),少写很多forward&#xff0c;适合直连式网络 代码来源&#xff1a;https://github.com/zshhans/MSD-Mixer/b…

用C爬取人人文库并分析实现免积分下载资料

最近有个学妹学习遇到问题&#xff0c;想要的学习资料都在文库中&#xff0c;因为资料太多太杂&#xff0c;想要一篇篇找太难了&#xff0c;主要是太浪费精力了。因此&#xff0c;听说这个事情我能解决&#xff0c;立马找到我&#xff0c;给我一杯奶茶就把我收买了&#xff0c;…

node.js mongoose index(索引)

目录 简介 索引类型 单索引 复合索引 文本索引 简介 在 Mongoose 中&#xff0c;索引&#xff08;Index&#xff09;是一种用于提高查询性能的数据结构&#xff0c;它可以加速对数据库中文档的检索操作 索引类型 单索引、复合索引、文本索引、多键索引、哈希索引、地理…

ChatGPT一周年:开源语言大模型的冲击

自2022年末发布后&#xff0c;ChatGPT给人工智能的研究和商业领域带来了巨大变革。通过有监督微调和人类反馈的强化学习&#xff0c;模型可以回答人类问题&#xff0c;并在广泛的任务范围内遵循指令。在获得这一成功之后&#xff0c;人们对LLM的兴趣不断增加&#xff0c;新的LL…

听GPT 讲Rust源代码--src/tools(18)

File: rust/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs 在Rust源代码中的from_comment.rs文件位于Rust分析器&#xff08;rust-analyzer&#xff09;工具的ide-ssr库中&#xff0c;它的作用是将注释转换为Rust代码。 具体来说&#xff0c;该文件实现了从注…

数据库学习日常案例20231221-oracle libray cache lock分析

1 问题概述&#xff1a; 阻塞的源头为两个ddl操作导致大量的libray cache lock 其中1133为gis sde的create table as语句。 其中697为alter index语句。

微软官方出品:GPT大模型编排工具,支持C#、Python等多个语言版本

随着ChatGPT的火热&#xff0c;基于大模型开发应用已经成为新的风口。虽然目前的大型模型已经具备相当高的智能水平&#xff0c;但它们仍然无法完全实现业务流程的自动化&#xff0c;从而达到用户的目标。 微软官方开源的Semantic Kernel的AI编排工具&#xff0c;就可以很好的…

用户管理第2节课--idea 2023.2 后端--实现基本数据库操作(操作user表) -- 自动生成

一、插件 Settings... 1.1 File -- Settings 1.2 Settings -- Plugins 1.2.1 搜索框&#xff0c;也可以直接搜索 1.3 Plugins -- 【输入 & 搜索】mybatis 1.3.1 插件不同功能介绍 1.3.2 翻译如下 1.4 选中 Update&#xff0c;更新下 1.4.1 更新中 1.4.2 Restart IDE 1…

Java数据结构-模拟ArrayList集合思想,手写底层源码(1),底层数据结构是数组,编写add添加方法,正序打印和倒叙打印

package com.atguigu.structure; public class Demo02_arrayList {public static void main(String[] args) {MyGenericArrayListV1 arrayListV1 new MyGenericArrayListV1();//arr.add(element:100,index:1);下标越界&#xff0c;无法插入//初始化&#xff08;第一次添加&…

selenium 报错

selenium 报错 开始学自动化测试&#xff0c;&#xff0c;环境配了一天TAT 安装好selenium之后 运行python脚本 # codingutf-8 from selenium import webdriver import timedriver webdriver.Chrome() driver.get("https://www.baidu.com") time.sleep(3) driver.…