当前位置:网站首页>【QT小点】实现看门狗功能,检测外部程序是否在运行

【QT小点】实现看门狗功能,检测外部程序是否在运行

2022-06-27 05:46:00 林柒Sevenlin

看门狗功能

  • 检测外部程序是否在运行,若未运行,则启动外部程序
  • 在子线程中实现,不卡主界面
  • 可检测多个外部程序

.h文件

#ifndef WATCHDOGTHREAD_H
#define WATCHDOGTHREAD_H

#include <QObject>
#include <QThread>
#include <QMap>

class WatchDogThread : public QThread
{
    Q_OBJECT
public:
    WatchDogThread();

public:
    // 添加外部程序绝对路径(路径不能带空格)
    void appendProcess(const QString &processPath);
    void appendProcess(const QList<QString> &processPathList);

    // 设置检测频率
    void setInterval(int msec);

protected:
    void run() override;

private:
    // 检测程序是否正在运行
    bool checkProcess(const QString &processName);

    // 启动外部程序
    bool startProcess(const QString &processPath);

signals:
    void signal_sendMsg(const QString &msg);

private:
    QMap<QString, QString> m_processMap;  // key: 程序名  value: 程序绝对路径
    int m_interval;  // 检测频率
};

#endif // WATCHDOGTHREAD_H

.cpp文件

#include "watchdogthread.h"
#include <QTimer>
#include <QProcess>

WatchDogThread::WatchDogThread()
{
    m_interval = 1000 * 3;
}

void WatchDogThread::appendProcess(const QString &processPath)
{
    QString processName = processPath.split("/").last();
    m_processMap.insert(processName, processPath);
}

void WatchDogThread::appendProcess(const QList<QString> &processPathList)
{
    for (const auto &path : processPathList) {
        QString processName = path.split("/").last();
        m_processMap.insert(processName, path);
    }
}

void WatchDogThread::setInterval(int msec)
{
    m_interval = msec;
}

void WatchDogThread::run()
{
    QTimer timer;
    timer.setInterval(m_interval);
    connect(&timer, &QTimer::timeout, this, [&] {
        QList<QString> processNameList = m_processMap.keys();
        for (const auto &name : processNameList) {
            if (checkProcess(name)) {

            } else {
                if (startProcess(m_processMap.value(name))) {
                    emit signal_sendMsg(QString("程序[%1]重新启动成功").arg(name));
                } else {
                    emit signal_sendMsg(QString("程序[%1]重新启动失败").arg(name));
                }
            }
        }
    });

    timer.start();
    exec();
}

bool WatchDogThread::checkProcess(const QString &processName)
{
    QProcess process;

#ifdef Q_OS_WIN
    /***
    tasklist 查看系统任务列表
    /fi (filter) 显示一系列符合筛选器指定的进程
    eq 相等
    imagename 映像名称

    eg: tasklist /fi "imagename eq QtCreator.exe"
    映像名称                       PID 会话名              会话#       内存使用
    ========================= ======== ================ =========== ============
    qtcreator.exe                22188 Console                    1    133,732 K
    qtcreator.exe                21008 Console                    1    189,648 K
    ***/
    QString cmd = QString("tasklist /fi \"imagename eq %1\"").arg(processName);
    process.start(cmd);
#else
    QStringList arguments;
    arguments << QString("-c");  // 需要加个-c参数命令才能执行
    arguments << QString("ps -A | grep %1").arg(processName);
    process.start("bash", arguments);
#endif

    process.waitForFinished();

    QString result = QString::fromLocal8Bit(process.readAllStandardOutput());
    if (result.contains(processName, Qt::CaseInsensitive)) {
        return true;
    }

    return false;
}

bool WatchDogThread::startProcess(const QString &processPath)
{
    // 路径带空格,使用带参模式,可以启动
    // process->start("C:/Program Files/Exe/111.exe", QStringList("C:/Program Files/Exe/111.exe"));
    return QProcess::startDetached(processPath);
}

原网站

版权声明
本文为[林柒Sevenlin]所创,转载请带上原文链接,感谢
https://blog.csdn.net/lin786063594/article/details/125070551