简述

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

  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

任务列表

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

更多参考

Qt之运行一个实例进程的更多相关文章

  1. 如何用Qt写一个同一时间只能运行一个实例的应用程序

    http://blog.sina.com.cn/s/blog_6343941a0100nk2x.html 可以达到的目的: 1.应用只启动一个实例,依赖于QtNetwork模块 2.启动时向另一个实例 ...

  2. Linux编程之《只运行一个实例》

    概述 有些时候,我们要求一个程序在系统中只能启动一个实例.比如,Windows自带的播放软件Windows Medea Player在Windows里就只能启动一个实例.原因很简单,如果同时启动几个实 ...

  3. 解决C#程序只允许运行一个实例的几种方法详解

    解决C#程序只允许运行一个实例的几种方法详解 本篇文章是对C#中程序只允许运行一个实例的几种方法进行了详细的分析介绍,需要的朋友参考下 本文和大家讲一下如何使用C#来创建系统中只能有该程序的一个实例运 ...

  4. C#让应用程序只运行一个实例的几种方法

    一 判断是否有相同的实例已经运行 1 根据“Mutex”判断是否有相同的实例在运行 /// <returns>已有实例运行返回true,否则为false</returns>pu ...

  5. C# WINFORM判断程序是否运行,且只能运行一个实例(转)

    判断程序是否已经运行,使程序只能运行一个实例有很多方法,下面记录两种, 方法1:线程互斥 static class Program { private static System.Threading. ...

  6. WinForm判断程序是否已经在运行,且只允许运行一个实例

    我们开发WinFrom程序,很多时候都希望程序只有一个实例在运行,避免运行多个同样的程序,一是没有意义,二是容易出错. 为了更便于使用,笔者整理了一段自己用的代码,可以判断程序是否在运行,只运行一个实 ...

  7. VC 实现程序只运行一个实例,并激活已运行的程序

    转载:http://blog.sina.com.cn/s/blog_4b44e1c00100bh69.html 进程的互斥运行:CreateMutex函数实现只运行一个程序实例 正常情况下,一个进程的 ...

  8. winform判断程序是否运行,且只能运行一个实例

    前言 判断程序是否已经运行,使程序只能运行一个实例有很多方法,下面记录两种. 目前使用的是第一种方法. 方法1:线程互斥 static class Program { private static S ...

  9. C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper

    前言 在开发应用程序时,通常只让程序运行一个实例.所以,就要判断程序是否已经运行. 下面是我自己在项目中使用到,封装好的帮助类.有 普通的 C# 应用程序 和 Windows CE 和 Windows ...

随机推荐

  1. Could not find file '..\bin\hibernate.cfg.xml'解决方法:

    web.config: 解决方法:

  2. 爬虫-html

    Uri myUri =new Uri(@sURL); WebRequest wrq = WebRequest.Create(myUri); WebResponse wrs = wrq.GetRespo ...

  3. 一点简单的关于ASP.NET下载

    一点简单的关于ASP.NET下载 个人简单的认为是有两种方法的,第一种就是直接用一个超链接链接到我们要下载的资源就可以了.只是说这个方法会有一点小问题就是,比如像图片或者文本文件这些浏览器是可以自动将 ...

  4. TS流格式(转)

    一 从TS流开始 数字电视机顶盒接收到的是一段段的码流,我们称之为TS(Transport Stream,传输流),每个TS流都携带一些信息,如Video.Audio以及我们需要学习的PAT.PMT等 ...

  5. 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!

    // test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  6. oracle——外连接查询

    一.问题描述 有时我们为了保留某个表中的数据,而该表中的数据在另外一个关联表中未必都存在对应,此时就应该试用外连接查询. 比如:两个表,产品表和子产品表 注:子产品的parent_product_id ...

  7. NGINX的奇淫技巧 —— 6. IF实现数学比较功能 (1)

    NGINX的奇淫技巧 —— 6. IF实现数学比较功能 (1) ARGUS 1月13日 发布 推荐 0 推荐 收藏 3 收藏,839 浏览 nginx的if支持=.!= 逻辑比较, 但不支持if中 & ...

  8. 自定义nagios check_load告警阀值

    自定义nagios  check_load告警阀值 日期:2012-01-11 来源: heipark 分享至: - 默认check_load配置 define service{ use generi ...

  9. POJ 3228 Gold Transportation(带权并查集,好题)

    参考链接:http://www.cnblogs.com/jiaohuang/archive/2010/11/13/1876418.html 题意:地图上某些点有金子,有些点有房子,还有一些带权路径,问 ...

  10. [转] 浅析HTTP协议

    浅析HTTP协议 来源:http://www.cnblogs.com/gpcuster/archive/2009/05/25/1488749.html HTTP协议是什么? 简单来说,就是一个基于应用 ...