Single Application
如果限制一个程序同时只能启动一个实例,有几个可以使用的库
QtSingleApplication
以前可以免费使用,后来只有商业版能里能用,在 Github 上也有一个 LGPL 协议的实现,地址为https://github.com/qtproject/qt-solutions/tree/master/qtsingleapplication
SingleApplication
This is a replacement of the QSingleApplication for Qt5,地址为 https://github.com/itay-grudev/SingleApplication
RunGuard
使用共享内存、简单、轻量化的实现,缺点是程序间不能通信,双击程序图标的时候不会激活已运行的实例显示到最前面,下面介绍 RunGuard 的使用
main.cpp
限制程序同时只能启动一个实例只需要在 main() 函数里调用 if (!guard.tryToRun()) { return 0; } 即可。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
#include "RunGuard.h"
int main(int argc, char *argv[]) {
RunGuard guard("9F0FFF1A-77A0-4EF0-87F4-5494CA8181C7");
if (!guard.tryToRun()) {
return 0;
}
QApplication a(argc, argv);
a.exec();
}
|
RunGuard.h
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
#ifndef RUNGUARD_H
#define RUNGUARD_H
#include <QObject>
#include <QSharedMemory>
#include <QSystemSemaphore>
class RunGuard {
public:
RunGuard(const QString& key);
~RunGuard();
bool isAnotherRunning();
bool tryToRun();
void release();
private:
const QString key;
const QString memLockKey;
const QString sharedmemKey;
QSharedMemory sharedMem;
QSystemSemaphore memLock;
Q_DISABLE_COPY(RunGuard)
};
#endif // RUNGUARD_H
|
RunGuard.cpp
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
|
#include "RunGuard.h"
#include <QCryptographicHash>
namespace {
QString generateKeyHash(const QString& key, const QString& salt) {
QByteArray data;
data.append(key.toUtf8());
data.append(salt.toUtf8());
data = QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex();
return data;
}
}
RunGuard::RunGuard(const QString &key)
: key(key)
, memLockKey(generateKeyHash(key, "_memLockKey"))
, sharedmemKey(generateKeyHash(key, "_sharedmemKey"))
, sharedMem(sharedmemKey)
, memLock(memLockKey, 1) {
memLock.acquire();
{
QSharedMemory fix(sharedmemKey); // Fix for *nix: http://habrahabr.ru/post/173281/
fix.attach();
}
memLock.release();
}
RunGuard::~RunGuard() {
release();
}
bool RunGuard::isAnotherRunning() {
if (sharedMem.isAttached()) {
return false;
}
memLock.acquire();
const bool isRunning = sharedMem.attach();
if (isRunning) {
sharedMem.detach();
}
memLock.release();
return isRunning;
}
bool RunGuard::tryToRun() {
if (isAnotherRunning()) { // Extra check
return false;
}
memLock.acquire();
const bool result = sharedMem.create(sizeof(quint64));
memLock.release();
if (!result) {
release();
return false;
}
return true;
}
void RunGuard::release() {
memLock.acquire();
if (sharedMem.isAttached()) {
sharedMem.detach();
}
memLock.release();
}
|
http://www.qtdebug.com/qtbook-misc-single-application/
Single Application的更多相关文章
- How to: Use Both Entity Framework and XPO in a Single Application 如何:在单个应用程序中同时使用实体框架和 XPO
This topic demonstrates how to create a simple XAF application that uses both the Entity Framework ( ...
- 4: 模块化应用程序开发 Modular Application Development Using Prism Library 5.0 for WPF (英汉对照版)
A modular application is an application that is divided into a set of loosely coupled functional uni ...
- Concurrency and Application Design
Concurrency and Application Design In the early days of computing, the maximum amount of work per un ...
- difference in physical path, root path, virutal path, relative virtual path, application path and aboslute path?
http://stackoverflow.com/questions/13869817/difference-in-physical-path-root-path-virutal-path-relat ...
- Understanding IIS Bindings, Websites, Virtual Directories, and lastly Application Pools
In a recent meeting, some folks on my team needed some guidance on load testing the Web application ...
- External Configuration Store Pattern 外部配置存储模式
Move configuration information out of the application deployment package to a centralized location. ...
- 数据库管理工具GUI - PremiumSoft Navicat Premium Enterprise 11.2.15 x86/x64 KEY
转载自: 数据库管理工具GUI - PremiumSoft Navicat Premium Enterprise 11.2.15 x86/x64 KEY Navicat Premium(数据库管理工具 ...
- Android Support Library
title: Android Support Library tags: Support Library,支持库 grammar_cjkRuby: true --- DATE: 2016-5-13. ...
- Spring Boot文档阅读
原因之初 最初习惯百度各种博客教程,然后跟着操作,因为觉得跟着别人走过的路走可以少走很多弯路,省时间.然而,很多博客的内容并不够完整,甚至错误,看多了的博客甚至有千篇一律的感觉.此外,博客毕竟是记载博 ...
随机推荐
- [Recompose] Transform Props using Recompose --mapProps
Learn how to use the 'mapProps' higher-order component to modify an existing component’s API (its pr ...
- JavaScript中的一些细节 分类: C1_HTML/JS/JQUERY 2014-08-05 16:45 384人阅读 评论(0) 收藏
1.设置id / class等属性 用 setAttribute 设置一些常规属性如 id ,className 的时候经常不起作用,只能用 object.id = value 这样来设置 news_ ...
- Java中String推断相等equals与==的差别以及StringBuilder的equals
Java中String类型具有一个equals的方法能够用于推断两种字符串是否相等,可是这样的相等又与运算符==所推断的"相等"有所不同,接下来进行分析,结论由程序进行验证 Str ...
- web网站如何实现兼容手机
web网站如何实现兼容手机 一.总结 一句话总结:加上这句话即可:<meta name="viewport" content="width=device-width ...
- spring boot中servlet启动原理
启动过程及原理 1 spring boot 应用启动运行run方法 StopWatch stopWatch = new StopWatch(); stopWatch.start(); Configur ...
- SQLServer重建索引
Use [数据库名称]Go DECLARE @DBCCString NVARCHAR(1000)DECLARE @TableName VARCHAR(100)DECLARE Cur_Index CUR ...
- 【u028】数列的整除性
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 对于任意一个整数数列,我们可以在每两个整数中间任意放一个符号'+'或'-',这样就可以构成一个表达式, ...
- J2EE学习篇之--JQuery技术具体解释
前面我们解说了的J2EE的技术都是服务端的技术,以下我们来看一下前端的一些开发技术,这一篇我们来看一下jQuery技术 简单介绍: jQuery由美国人John Resig创建,至今已吸引了来自世界各 ...
- [Redux] Important things in Redux
Root Smart component can be overloaded, divide 'smart' component wisely & using Provider. Proble ...
- Indy10 控件的使用(2)TidTCpServer组件学习
以下来自英文原版帮助文件,文桓英语不好,翻译了老半天.有错误的地方见谅,别骂我. TIdTCPServer = class(TIdComponent) Description TIdTCPServer ...