将qt程序注册成服务

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

上市公司-客户、供应商集中度(2000-2022年)

参考《中国工业经济》中吴安兵&#xff08;2023&#xff09;、《上海财经大学学报》中邱保印&#xff08;2023&#xff09;的做法&#xff0c;以客户集中度和供应商集中度之和衡量企业供应链集中度 其中客户集中度以前五名客户产生的营业收入占比衡量&#xff0c;供应商集中度…

好物设计- 实现区域图片变化自动截图

工具–Py即可 重点怎么获取窗口句柄? 使用 spyxx 可以获得句柄 (相当一个窗口的ID,无论窗口怎么变化ID不变我们都可以找到该窗口的详细信息) 替换句柄就可以,也可以不用句柄之间改截图区域 实战图片 import pygetwindow as gw import pyautogui import time import numpy a…

工业交换机之间Profinet无线以太网通信

在实际应用中&#xff0c;车间里控制柜内会有PLC、伺服电机、变频器等设备同时与触摸屏做数据交互&#xff0c;这些设备一般通过工业交换机进行数据组网。总控室内的PC组态软件往往需要采集到&#xff0c;车间内各部分触摸屏、PLC、变频器等设备信号&#xff0c;此时往往是工业…

当代大学生应该如何学习计算机科学

我相信&#xff0c;看到这个标题并且愿意阅读往下阅读的你&#xff0c;一定是正在学习计算机&#xff0c;而自己感到迷茫&#xff0c;或者你还真在考虑要不要学习计算机科学&#xff0c;再或者你是想学计算机而不知道到底该怎么去学的&#xff0c;好&#xff0c;既然你是榜上有…

ssm基于JAVA的校园综合服务系统论文

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自古…

代码随想录第三十六天(一刷C语言)|背包问题理论基础分割等和子集

创作目的&#xff1a;为了方便自己后续复习重点&#xff0c;以及养成写博客的习惯。 一、背包问题 题目&#xff1a;有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解将哪些物品装…

【C#】.net core 6.0 通过依赖注入注册和使用上下文服务

给自己一个目标&#xff0c;然后坚持一段时间&#xff0c;总会有收获和感悟&#xff01; 请求上下文是指在 Web 应用程序中处理请求时&#xff0c;包含有关当前请求的各种信息的对象。这些信息包括请求的头部、身体、查询字符串、路由数据、用户身份验证信息以及其他与请求相关…

Android 自动适配屏幕方案—— smallestWidth

smallestWidth限定符适配原理和屏幕分辨率限定符适配一样&#xff0c;都是通过创建多个values文件夹&#xff0c;系统根据限定符去寻找对应的dimens.xml文件&#xff0c;以确定不同设备上的大小展示&#xff0c;smallestWidth 限定符适配是拿 dp 值来等比缩放. 如何使用 一、…

低代码和纯代码:双向奔赴,共创未来ing……

低代码开发是近年来迅速崛起的软件开发方法&#xff0c;让编写应用程序变得更快、更简单。有人说它是美味的膳食&#xff0c;让开发过程高效而满足&#xff0c;但也有人质疑它是垃圾食品&#xff0c;缺乏定制性与深度。你认为低代码到底是美味的膳食还是垃圾食品呢&#xff0c;…

如何快速优化大数据量订单表

场景 本篇分享以前在广州一家互联网公司工作时遇到的状况及解决方案,这家公司有一个项目是SOA的架构,这个架构那几年是很流行的,哪怕是现在依然认为这个理念在当时比较先进。 当时的项目背景大概是这样,这家公司用的是某软提供的方案,项目已经运行3年多,整体稳定。 数据…

轴具匠心 SIA上海轴承展带您开启轴承之旅

轴承是各类机械装备的重要基础零部件&#xff0c;它的精度、性能、寿命和可靠性对主机的工作效率、使用寿命起着决定性的作用。随着市场的发展&#xff0c;用户对轴承产品的精度、性能、种类等方面的要求越来越高&#xff0c;市场对高档轴承的需求也在不断增加。 由中国设备管理…

Android中EventBus的简单使用

目录 介绍 EventBus产生的背景 EventBus工作流程图解 EventBus的优势 EventBus缺点 EventBus 的一些关键概念和用法&#xff1a; 使用 EventBus 的基本流程&#xff1a; EventBus环境配置 EventBus的五种线程模式 EventBus的使用 EventBus事件三部曲 创建一个事件类…

SE-Net:Squeeze-and-Excitation Networks(CVPR2018)

文章目录 AbstractIntroduction表征的重要性以前的方向本文提出 Related WorkDeeper ArchitectureAlgorithmic Architecture SearchAttention and gating mechanisms Squeeze-and-Excitation BlocksSqueeze: Global Information EmbeddingExcitation: Adaptive RecalibrationIn…

ssm基于vue的厨房管理系统论文

摘 要 使用旧方法对厨房管理信息进行系统化管理已经不再让人们信赖了&#xff0c;把现在的网络信息技术运用在厨房管理信息的管理上面可以解决许多信息管理上面的难题&#xff0c;比如处理数据时间很长&#xff0c;数据存在错误不能及时纠正等问题。 这次开发的厨房管理系统管…

【Python-批量修改视频分辨率】

Python-批量修改视频分辨率 1 使用Python修改视频分辨率2 常见的视频编码格式2.1 等效的编码格式表示方式2.2 常见的编码格式 1 使用Python修改视频分辨率 首先拷贝视频文件并修改后缀&#xff0c;然后修改图片的分辨率&#xff0c;实现视频批量修改和转换。 import os impor…

自定义注解实现 后台系统-记录日志功能

文章目录 1 记录日志1.1 记录日志的意义1.2 日志数据表结构1.3 记录日志思想1.4 切面类环境搭建1.4.1 日志模块创建1.4.2 自定义Log注解1.4.3 OperatorType1.4.4 LogAspect1.4.5 EnableLogAspect1.4.6 测试日志切面类 1.5 保存日志数据1.5.1 SysOperLog1.5.2 LogAspect1.5.3 As…

【教程】cocos2dx资源加密混淆方案详解

1,加密,采用blowfish或其他 2,自定是32个字符的混淆code 3,对文件做blowfish加密,入口文件加密前将混淆code按约定格式(自定义的文件头或文件尾部)写入到文件 4,遍历资源目录,对每个文件做md5混淆,混淆原始串“相对路径”“文件名”混淆code, 文件改名并且移动到资源目录根…

C# try-catch异常处理的用法

try-catch 是一种在编程语言中用于捕获和处理异常的结构。它的作用是在可能引发异常的代码块中进行异常处理&#xff0c;以避免程序崩溃或产生不可预料的结果。 当在 try 块中的代码执行时&#xff0c;如果发生了异常&#xff0c;程序会立即跳转到对应的 catch 块。catch…

http客户端Feign

http客户端Feign 文章目录 http客户端Feign定义和使用Feign客户端自定义Feign的配置Feign的性能优化feign的最佳实践 定义和使用Feign客户端 <!-- feign客户端依赖--><dependency><groupId>org.springframework.cloud</groupId><artifactId>s…

为什么C语言没有被C++所取代呢?

今日话题&#xff0c;为什么C语言没有被C所取代呢&#xff1f;虽然C是一个功能更强大的语言&#xff0c;但C语言在嵌入式领域仍然广泛使用&#xff0c;因为它更轻量级、更具可移植性&#xff0c;并且更适合在资源受限的环境中工作。这就是为什么C语言没有被C所取代的原因。如果…