Qt之运行一个实例进程

简介: 简述发布程序的时候,我们往往会遇到这种情况:只需要用户运行一个实例进程用户可以同时运行多个实例进程一个实例进程的软件有很多,例如:360、酷狗… 多个实例进程的软件也很多,例如:Visual Studio、Qt Ctretor、QQ…下面我们来介绍下如何实现一个实例进程。简述QSharedMemoryQLocalServerQtSing
+关注继续查看

简述

发布程序的时候,我们往往会遇到这种情况:

  1. 只需要用户运行一个实例进程
  2. 用户可以同时运行多个实例进程

一个实例进程的软件有很多,例如:360、酷狗…
多个实例进程的软件也很多,例如:Visual Studio、Qt Ctretor、QQ…

下面我们来介绍下如何实现一个实例进程。

QSharedMemory

使用共享内存来实现,key值唯一,一般可以用组织名+应用名来确定。

首先,创建一个共享内存区,当第二个进程启动时,判断内存区数据是否建立,如果有,可以激活已打开的窗体,也可以退出。

当程序crash的时候,不能及时清除共享区数据,导致程序以后不能正常启动。

int main(int argc, char **argv)
{
    QApplication app(argc, argv);

    QCoreApplication::setOrganizationName("Company");
    QCoreApplication::setApplicationName("AppName");
    QString strKey = QCoreApplication::organizationName() + QCoreApplication::applicationName();

    QSharedMemory sharedMemory(strKey);
    if (!sharedMemory.create(512, QSharedMemory::ReadWrite))
    {
        QMessageBox::information(NULL, QStringLiteral("提示"), QStringLiteral("程序已运行!"));
        exit(0);
    }

    MainWindow window;
    window.show();

    return app.exec();
}

QLocalServer

QSingleApplication.h

#ifndef SINGLE_APPLICATION_H
#define SINGLE_APPLICATION_H

#include <QApplication>

class QLocalServer;

class QSingleApplication : public QApplication
{
    Q_OBJECT

public:
    explicit QSingleApplication(int argc, char **argv);
    // 判断进程是否存在
    bool isRunning();

private slots:
    void newLocalConnection();

private:
    QLocalServer *m_pServer;
    bool m_bRunning;
};

#endif // SINGLE_APPLICATION_H

QSingleApplication.cpp

#include <QLocalSocket>
#include <QLocalServer>
#include <QFile>
#include <QTextStream>
#include "QSingleApplication.h"

QSingleApplication::QSingleApplication(int argc, char **argv)
    : QApplication(argc, argv),
      m_bRunning(false)
{
    QCoreApplication::setOrganizationName("Company");
    QCoreApplication::setApplicationName("AppName");
    QString strServerName = QCoreApplication::organizationName() + QCoreApplication::applicationName();

    QLocalSocket socket;
    socket.connectToServer(strServerName);

    if (socket.waitForConnected(500))
    {
        QTextStream stream(&socket);
        QStringList args = QCoreApplication::arguments();

        QString strArg = (args.count() > 1) ? args.last() : "";
        stream << strArg;
        stream.flush();
        qDebug() << "Have already connected to server.";

        socket.waitForBytesWritten();

        m_bRunning = true;
    }
    else
    {
        // 如果不能连接到服务器,则创建一个
        m_pServer = new QLocalServer(this);
        connect(m_pServer, SIGNAL(newConnection()), this, SLOT(newLocalConnection()));

        if (m_pServer->listen(strServerName))
        {
            // 防止程序崩溃,残留进程服务,直接移除
            if ((m_pServer->serverError() == QAbstractSocket::AddressInUseError) && QFile::exists(m_pServer->serverName()))
            {
                QFile::remove(m_pServer->serverName());
                m_pServer->listen(strServerName);
            }
        }
    }
}

void QSingleApplication::newLocalConnection()
{
    QLocalSocket *pSocket = m_pServer->nextPendingConnection();
    if (pSocket != NULL)
    {
        pSocket->waitForReadyRead(1000);

        QTextStream in(pSocket);
        QString strValue;
        in >> strValue;
        qDebug() << QString("The value is: %1").arg(strValue);

        delete pSocket;
        pSocket = NULL;
    }
}

bool QSingleApplication::isRunning()
{
    return m_bRunning;
}

使用方式

int main(int argc, char **argv)
{
    QSingleApplication app(argc,argv);
    if (app.isRunning())
    {
        QMessageBox::information(NULL, QStringLiteral("提示"), QStringLiteral("程序已运行!"));
        exit(0);
    }

    MainWindow window;
    window.show();

    return app.exec();
}

QtSingleApplication

QSingleApplication位于qt-solution里面,并不包含在Qt库中,遵循 LGPL 协议。

文档、源码、示例见:QtSingleApplication

任务列表

运行程序时,遍历任务列表,查看是当前所有运行中的进程,如果当前进程位置在映射路径中可以找到,则说明程序已经运行,否则,未运行。

更多参考

目录
相关文章
|
5月前
Qt通过QProcess启动进程并传递命令行参数
Qt通过QProcess启动进程并传递命令行参数
281 0
|
11月前
|
安全 Windows
vb得到一个进程的启动参数?
vb得到一个进程的启动参数?
91 0
|
11月前
|
人工智能 监控 算法
西门子S7-200 SMART PID控制实例,如何配置PID向导、调用子程序?如何创建状态图表测试程序?如何自整定PID参数?
PID控制器是应用最广泛的闭环控制器,它根据给定值与被控变量实测值之间的偏差,按照PID算法计算出控制器的输出量控制执行机构进行调节,使被控量跟随给定量进行变化并使系统达到稳定,自动消除各种干扰对控制过程的影响,其中P、I、D分别指比例、积分、微分。
西门子S7-200 SMART PID控制实例,如何配置PID向导、调用子程序?如何创建状态图表测试程序?如何自整定PID参数?
|
Linux 测试技术 iOS开发
【实测】windows下进程的创建和终止-python3
【实测】windows下进程的创建和终止-python3
Qt窗口关闭和应用程序停止是否调用析构函数的一些说明
Qt窗口关闭和应用程序停止是否调用析构函数的一些说明
Qt窗口关闭和应用程序停止是否调用析构函数的一些说明
|
C++ Windows
windows启动单个进程实例(系统中只有一个运行实例)
windows启动单个进程实例(系统中只有一个运行实例)
155 0
windows启动单个进程实例(系统中只有一个运行实例)
|
开发工具 Android开发
【错误记录】OD 调试器附加进程时找不到进程 ( CE 工具可以附加进程 )
【错误记录】OD 调试器附加进程时找不到进程 ( CE 工具可以附加进程 )
707 0
【错误记录】OD 调试器附加进程时找不到进程 ( CE 工具可以附加进程 )
|
Windows
Windows 技术篇-任务管理器查看执行进程的程序所在位置方法,查看执行进程的命令行
Windows 技术篇-任务管理器查看执行进程的程序所在位置方法,查看执行进程的命令行
226 0
Windows 技术篇-任务管理器查看执行进程的程序所在位置方法,查看执行进程的命令行
推荐文章
更多
推荐镜像
更多