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

Qt 进程守护程序

Qt 进程守护程序

简单粗暴的监控,方法可整合到其他代码。

一、windows环境下
1、进程查询函数
processCount函数用于查询系统所有运行的进程中该进程运行的数量,比如启动了5个A进程,该函数查询返回的结果就为5。
windows下使用了API接口查询进程信息,该函数纯C++无Qt库相关代码,注释对代码进行了详细解释。

int processCount(const char*  processName)
{int countProcess = 0;//CreateToolhelp32Snapshot 获取系统中正在运行的进程信息,线程信息等HANDLE toolHelp32Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);if (((int)toolHelp32Snapshot) != -1){PROCESSENTRY32 processEntry32;processEntry32.dwSize = sizeof(processEntry32);if(Process32First(toolHelp32Snapshot, &processEntry32))      //判断进程获取首进程是否存在{do{int iLen = 2 * wcslen(processEntry32.szExeFile);    //wcslen - 计算宽字符串的长度char* currentProcessName = new char[iLen + 1];wcstombs(currentProcessName, processEntry32.szExeFile, iLen + 1);    //将宽字符转换成多字符if (strcmp(processName, currentProcessName) == 0)      //对比进程名countProcess++;delete []currentProcessName;}while (Process32Next(toolHelp32Snapshot, &processEntry32));     //进程获取函数,获取下一个进程名}//关闭一个内核对象。其中包括文件、文件映射、进程、线程、安全和同步对象等。CloseHandle(toolHelp32Snapshot);}return countProcess;
}

2、进程守护代码
进程守护其实就是使用一个进程去定时查询另外一个被守护的进程是否存在,不存在则需要启动该进程。代码如下,运行时,首先需要获取被守护的进程APP,使用读取配置文件的方式,如果配置文件不存在(首次启动该代码),则需要选择被守护的进程,然后将选择的APP路劲存入配置文件,供下次启动读取使用。

#include <QApplication>
#include <QFileDialog>
#include <QSettings>
#include <windows.h>
#include <QDebug>
#include <QDateTime>int main(int argc, char *argv[])
{QSettings sets("sys.ini", QSettings::IniFormat);QString targetExePath = sets.value(KEY_EXE_PATH).toString();if ("" == targetExePath){//首次需要选择 被守护的进程QString exepath = QFileDialog::getOpenFileName(nullptr, "选择程序", "D:/", "Exe files (*.exe)");if ("" != exepath)sets.setValue(KEY_EXE_PATH, exepath);       //写入配置文件}while (1)        //死循环,不断查询判断{//targetExePath = sets.value(KEY_EXE_PATH).toString();QString exeName = targetExePath.split('/').last();QDateTime strtTime = QDateTime::currentDateTime();int countProcess = processCount(exeName.toStdString().c_str());   // 查询该进程运行数量qDebug()<<"use times for Query process:"<<strtTime.msecsTo(QDateTime::currentDateTime())<<"(ms)   countProcess:"<<countProcess;if (countProcess == 0)system(targetExePath.toStdString().c_str());        //关闭状态 重启进程,注意:这里实际运行会阻塞在这里,一直等到被守护的线程结束。Sleep(3000);}
}

二、linux环境下
1、进程查询函数

原理: 使用 popen函数 + pidof命令 查询对应进程的pid,该方法的缺点就是不能像windows那样读取所有进程名从而获取该进程运行的数量。所以,如果一个程序加载多个进程(同程序进程名相同,pid不同),使用该方法只能获取最后一个启动的进程pid。

popen属于标准I/O函数库中函数,使用该函数启动另外一个进程去执行一个shell命令行。
这里我们称调用popen的进程为父进程,由popen启动的进程称为子进程。
popen函数还创建一个管道用于父子进程间通信。父进程要么从管道读信息,要么向管道写信息,至于是读还是写取决于父进程调用popen时传递的参数。

实现函数如下,函数参数输入进程名,返回进程的pid,如果返回0,则表示进程不存在或未运行。

void Widget::watchdog()
{//守护进程QTimer* updateTimer = new QTimer(this);connect(updateTimer, SIGNAL(timeout()), this, SLOT(checkApp()));updateTimer->start(300);
}
void Widget::checkApp()
{if (getProcessPidByName("AppName") == 0) {system("cd /sdcard");system("./AppName &");qDebug() << "";qDebug() << "  _  __                        _____  _                                 ";qDebug() << " | |/ /                       / ____|| |                                ";qDebug() << " | ' /   __ _  _ __    __ _  | |     | |__   _   _   __ _  _ __    __ _ ";qDebug() << " |  <   / _` || '_ \\  / _` | | |     | '_ \\ | | | | / _` || '_ \\  / _` |";qDebug() << " | . \\ | (_| || | | || (_| | | |____ | | | || |_| || (_| || | | || (_| |";qDebug() << " |_|\\_\\ \\__,_||_| |_| \\__, |  \\_____||_| |_| \\__,_| \\__,_||_| |_| \\__, |";qDebug() << "                      __/  |                                      __/  |";qDebug() << "                     |____/                                      |____/ ";qDebug() << "";}
}
int Widget::getProcessPidByName(const char* proc_name)
{FILE* fp;char buf[100];char cmd[200] = { '\0' };int pid = -1;sprintf(cmd, "pidof %s", proc_name);if ((fp = popen(cmd, "r")) != NULL) {if (fgets(buf, 255, fp) != NULL)pid = atoi(buf);}pclose(fp);return pid;
}
http://www.lryc.cn/news/299314.html

相关文章:

  • Linux_文件系统
  • 算法沉淀——链表(leetcode真题剖析)
  • Flink从入门到实践(一):Flink入门、Flink部署
  • python分离字符串 2022年12月青少年电子学会等级考试 中小学生python编程等级考试二级真题答案解析
  • Excel练习:折线图突出最大最小值
  • 鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之MenuItem组件
  • Mockito测试框架中的方法详解
  • Atcoder ABC339 A - TLD
  • 企业级DevOps实战
  • C++中的new和delete
  • rtt设备io框架面向对象学习-dac设备
  • 腾讯云幻兽帕鲁服务器配置怎么选择合适?
  • 796. 子矩阵的和
  • 如何在 Python 中处理 Unicode
  • CSDN文章导出PDF整理状况一览
  • jmeter-05变量(用户定义变量,用户参数,csv文档参数化)
  • CSS之水平垂直居中
  • 2.8日学习打卡----初学RabbitMQ(三)
  • Unity学习笔记(零基础到就业)|Chapter02:C#基础
  • 容器化的基础概念:不可变基础设施解释:将服务器视为乐高积木,而非橡皮泥。
  • 智胜未来,新时代IT技术人风口攻略-第二版(弃稿)
  • Git分支和迭代流程
  • 数据库管理-第150期 Oracle Vector DB AI-02(20240212)
  • MySQL双写机制
  • uniapp的配置和使用
  • 【ES】--Elasticsearch的分词器深度研究
  • 【Langchain Agent研究】SalesGPT项目介绍(三)
  • Java安全 URLDNS链分析
  • 【网站项目】026校园美食交流系统
  • 使用raw.gitmirror.com替换raw.githubusercontent.com以解决brew upgrade python@3.12慢的问题