Qt之运行一个实例进程
简述
发布程序的时候,我们往往会遇到这种情况:
- 只需要用户运行一个实例进程
- 用户可以同时运行多个实例进程
一个实例进程的软件有很多,例如: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之运行一个实例进程的更多相关文章
- 如何用Qt写一个同一时间只能运行一个实例的应用程序
http://blog.sina.com.cn/s/blog_6343941a0100nk2x.html 可以达到的目的: 1.应用只启动一个实例,依赖于QtNetwork模块 2.启动时向另一个实例 ...
- Linux编程之《只运行一个实例》
概述 有些时候,我们要求一个程序在系统中只能启动一个实例.比如,Windows自带的播放软件Windows Medea Player在Windows里就只能启动一个实例.原因很简单,如果同时启动几个实 ...
- 解决C#程序只允许运行一个实例的几种方法详解
解决C#程序只允许运行一个实例的几种方法详解 本篇文章是对C#中程序只允许运行一个实例的几种方法进行了详细的分析介绍,需要的朋友参考下 本文和大家讲一下如何使用C#来创建系统中只能有该程序的一个实例运 ...
- C#让应用程序只运行一个实例的几种方法
一 判断是否有相同的实例已经运行 1 根据“Mutex”判断是否有相同的实例在运行 /// <returns>已有实例运行返回true,否则为false</returns>pu ...
- C# WINFORM判断程序是否运行,且只能运行一个实例(转)
判断程序是否已经运行,使程序只能运行一个实例有很多方法,下面记录两种, 方法1:线程互斥 static class Program { private static System.Threading. ...
- WinForm判断程序是否已经在运行,且只允许运行一个实例
我们开发WinFrom程序,很多时候都希望程序只有一个实例在运行,避免运行多个同样的程序,一是没有意义,二是容易出错. 为了更便于使用,笔者整理了一段自己用的代码,可以判断程序是否在运行,只运行一个实 ...
- VC 实现程序只运行一个实例,并激活已运行的程序
转载:http://blog.sina.com.cn/s/blog_4b44e1c00100bh69.html 进程的互斥运行:CreateMutex函数实现只运行一个程序实例 正常情况下,一个进程的 ...
- winform判断程序是否运行,且只能运行一个实例
前言 判断程序是否已经运行,使程序只能运行一个实例有很多方法,下面记录两种. 目前使用的是第一种方法. 方法1:线程互斥 static class Program { private static S ...
- C#[Win32&WinCE&WM]应用程序只能运行一个实例:MutexHelper
前言 在开发应用程序时,通常只让程序运行一个实例.所以,就要判断程序是否已经运行. 下面是我自己在项目中使用到,封装好的帮助类.有 普通的 C# 应用程序 和 Windows CE 和 Windows ...
随机推荐
- Could not find file '..\bin\hibernate.cfg.xml'解决方法:
web.config: 解决方法:
- 爬虫-html
Uri myUri =new Uri(@sURL); WebRequest wrq = WebRequest.Create(myUri); WebResponse wrs = wrq.GetRespo ...
- 一点简单的关于ASP.NET下载
一点简单的关于ASP.NET下载 个人简单的认为是有两种方法的,第一种就是直接用一个超链接链接到我们要下载的资源就可以了.只是说这个方法会有一点小问题就是,比如像图片或者文本文件这些浏览器是可以自动将 ...
- TS流格式(转)
一 从TS流开始 数字电视机顶盒接收到的是一段段的码流,我们称之为TS(Transport Stream,传输流),每个TS流都携带一些信息,如Video.Audio以及我们需要学习的PAT.PMT等 ...
- 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果。对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。是不是很简单?OK,搞定它!
// test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...
- oracle——外连接查询
一.问题描述 有时我们为了保留某个表中的数据,而该表中的数据在另外一个关联表中未必都存在对应,此时就应该试用外连接查询. 比如:两个表,产品表和子产品表 注:子产品的parent_product_id ...
- NGINX的奇淫技巧 —— 6. IF实现数学比较功能 (1)
NGINX的奇淫技巧 —— 6. IF实现数学比较功能 (1) ARGUS 1月13日 发布 推荐 0 推荐 收藏 3 收藏,839 浏览 nginx的if支持=.!= 逻辑比较, 但不支持if中 & ...
- 自定义nagios check_load告警阀值
自定义nagios check_load告警阀值 日期:2012-01-11 来源: heipark 分享至: - 默认check_load配置 define service{ use generi ...
- POJ 3228 Gold Transportation(带权并查集,好题)
参考链接:http://www.cnblogs.com/jiaohuang/archive/2010/11/13/1876418.html 题意:地图上某些点有金子,有些点有房子,还有一些带权路径,问 ...
- [转] 浅析HTTP协议
浅析HTTP协议 来源:http://www.cnblogs.com/gpcuster/archive/2009/05/25/1488749.html HTTP协议是什么? 简单来说,就是一个基于应用 ...