当前位置: 首页 > article >正文

Qt 应用程序转换为服务

一、在 Windows 上将 Qt 应用程序转换为服务

方法1:

  1. 创建一个 Windows 服务应用程序
    • Windows 服务应用程序是一个没有用户界面的后台进程,通常由 Win32 Service 模板创建,或者直接编写 main() 函数以实现服务逻辑。

  2. 修改 Qt 应用程序以实现服务功能
    • 如果你的 Qt 应用程序已经有了 UI,需要移除 UI 部分,因为服务不支持图形界面。

    • 使用 QCoreApplicationQApplication 类来实现非 GUI 应用。

  3. Windows 服务编程基础

    在 Windows 中,服务程序通常使用 Windows API StartServiceCtrlDispatcher 来注册服务并接收控制命令。你可以通过如下步骤将 Qt 应用程序转化为服务:

    定义服务入口: Windows 服务必须通过 ServiceMain函数启动。可以在 Qt 应用程序中定义一个类似的函数来替代主函数的逻辑。

#include <QCoreApplication>
#include <Windows.h>
​
SERVICE_STATUS serviceStatus;
SERVICE_STATUS_HANDLE hStatusHandle;
​
void ServiceMain(DWORD argc, LPTSTR *argv) {
    // 初始化服务状态
    serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
    serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    serviceStatus.dwCurrentState = SERVICE_RUNNING;
    serviceStatus.dwWin32ExitCode = 0;
    serviceStatus.dwServiceSpecificExitCode = 0;
    serviceStatus.dwCheckPoint = 0;
    serviceStatus.dwWaitHint = 0;
​
    hStatusHandle = RegisterServiceCtrlHandler(L"MyQtService", ServiceCtrlHandler);
    if (hStatusHandle == (SERVICE_STATUS_HANDLE)0) {
        return;
    }
​
    SetServiceStatus(hStatusHandle, &serviceStatus);
​
    // 执行你的 Qt 应用程序逻辑
    QCoreApplication app(argc, argv);
    // 在这里初始化 Qt 应用逻辑
    app.exec();
}
​
void ServiceCtrlHandler(DWORD dwCtrl) {
    switch (dwCtrl) {
    case SERVICE_CONTROL_STOP:
        serviceStatus.dwCurrentState = SERVICE_STOPPED;
        break;
    default:
        break;
    }
    SetServiceStatus(hStatusHandle, &serviceStatus);
}
​
int main(int argc, char *argv[]) {
    SERVICE_TABLE_ENTRY serviceTable[] = {
        {L"MyQtService", (LPSERVICE_MAIN_FUNCTION)ServiceMain},
        {NULL, NULL}
    };
​
    if (StartServiceCtrlDispatcher(serviceTable) == 0) {
        return -1;
    }
​
    return 0;
}
​

将程序注册为 Windows 服务: 使用 sc 命令或在注册表中添加相关条目,将应用程序注册为服务。

sc create MyQtService binPath= "C:\Path\To\YourQtApp.exe"

安装和启动服务: 你可以通过以下命令安装和启动服务:

sc start MyQtService
sc stop MyQtService

方法2:使用srvany.exe

img编辑

方法3:使用nssm实现,

  1. nssm下载地址:NSSM - the Non-Sucking Service Manager

  2. 解压后,将nssm放在任意目录下,使用powershell或者cmd,输入命令

.\nssm.exe install MyService "C:\myapp\myapp.exe"

安装MyService服务,服务名也可以是中文的 。在使用的时候一定是.\nssm.exe,后面的路径需要加双引号。

imgimg

右键可以对服务进行操作

img编辑

也可以通过命令的方式

img

下载链接:https://download.csdn.net/download/weixin_41882459/90186516

二、在 Linux 上将 Qt 应用程序转换为服务

1将 Qt 应用程序移植到无图形环境

  • 和 Windows 类似,Qt 应用程序的服务部分通常不需要图形界面。你可以使用 QCoreApplication 来替代 QApplication,这样你的应用将不会启动图形界面。

#include <QCoreApplication>
​
int main(int argc, char *argv[]) {
    QCoreApplication app(argc, argv);
    // 在此执行后台服务的业务逻辑
    return app.exec();
}

2.创建一个 systemd 服务单元文件: 在 Linux 系统上,通常使用 systemd 来管理服务。你需要创建一个 systemd 配置文件(位于 /etc/systemd/system/ 目录下),该文件描述了如何启动和管理你的服务。

例如,创建一个 myqtservice.service 文件:

[Unit]
Description=My Qt Service
After=network.target
​
[Service]
Type=simple
ExecStart=/path/to/your/qt/application
Restart=always
User=yourusername
Group=yourgroupname
​
[Install]
WantedBy=multi-user.target
​

3.安装并启动服务

  • .service 文件复制到 /etc/systemd/system/ 目录。

  • 重新加载 systemd 配置文件:

  • sudo systemctl daemon-reload
    启动服务:
    sudo systemctl start myqtservice
    设置开机启动:
sudo systemctl enable myqtservice

查看服务状态

sudo systemctl status myqtservice

三、服务中的常见问题

  1. 日志记录: 服务通常需要记录日志,因为它没有用户界面。你可以使用 QFile, QTextStream 或 Qt 的日志系统 (QLoggingCategory) 来记录日志。也可以将日志输出到系统的日志系统,如 syslog

  2. 停止和重启: 在 Windows 和 Linux 上,服务可能会接收到停止或重启的信号。确保你的程序在接收到这些信号时能够正确地清理资源。

总结

将 Qt 应用程序转化为服务的关键是:

  • 移除用户界面部分。

  • 在后台运行应用程序并确保服务能够正常启动、停止和重启。

  • 在 Windows 中使用 SERVICE_MAINStartServiceCtrlDispatcher 来创建服务,而在 Linux 中则使用 systemd 来管理服务。

通过这种方式,你可以将 Qt 应用程序变成一个后台服务,确保它在系统启动时自动运行,且无需用户交互。


http://www.kler.cn/a/453195.html

相关文章:

  • 分布式专题(10)之ShardingSphere分库分表实战指南
  • SpringBoot使用Validation校验参数
  • Redis学习(五)优惠券秒杀2——分布式锁
  • Docker数据库的主从复制
  • 事件抽取tr、ti、ar 和 ai的意思(触发词、事件类型、事件参数、参数的类型)
  • stm32基础(keil创建、Proteus仿真、点亮LED灯,7段数码管)
  • MySQL基础-事务
  • 代码随想录算法【Day2】
  • Docker Run使用方法及参数详细说明
  • 【mysql】id主键列乱了之后,重新排序(可根据日期顺序)
  • 4.5 数据表的外连接
  • 【c++笔试强训】(第四十五篇)
  • 基于c语言的union、字符串、格式化输入输出
  • 【Golang 面试题】每日 3 题(六)
  • 学习C++:书写hello world
  • 什么是微分
  • OCR实践-Table-Transformer
  • 【人工智能】用Python实现情感分析:从简单词典到深度学习方法的演进
  • 15 break和continue
  • Dockerfile的用法
  • 基于OpenCV和Python的人脸识别系统_django
  • Python------Pandas的数据结构
  • vue搭建简易前端
  • springboot497基于java国产动漫网站设计和实现(论文+源码)_kaic
  • Jenkins入门使用
  • AI+“国补”推动,市场高度关注相关供应链企业