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文档阅读
原因之初 最初习惯百度各种博客教程,然后跟着操作,因为觉得跟着别人走过的路走可以少走很多弯路,省时间.然而,很多博客的内容并不够完整,甚至错误,看多了的博客甚至有千篇一律的感觉.此外,博客毕竟是记载博 ...
随机推荐
- Spring常用工具类(ApplicationContextAware、DisposableBean、InitializingBean)
原创作品,出自 "晓风残月xj" 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj). 由于各种原因,可能存在诸多不 ...
- [SCSS] Loop Over Data with the SCSS @each Control Directive
The SCSS @for directive is great when we know how many iterations are required and we only need 1 va ...
- JSON入门之二:org.json的基本用法 分类: C_OHTERS 2014-05-14 11:25 6001人阅读 评论(0) 收藏
java中用于解释json的主流工具有org.json.json-lib与gson,本文介绍org.json的应用. 官方文档: http://www.json.org/java/ http://de ...
- Android中的消息机制:Handler消息传递机制 分类: H1_ANDROID 2013-10-27 22:54 1755人阅读 评论(0) 收藏
参考<疯狂android讲义>第2版3.5 P214 一.背景 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为 ...
- Android 为开发者准备的最佳 Android 函数库(2016 年版)
本文是翻译自 CloudRAIL 的官方博客(https://cloudrail.com/best-android-libraries-for-developers/),本文中分享的 Android ...
- iOS过场动画调研笔记
前言 因项目须要,近期一段时间都在调研iOS的过场动画.对于我来说这是一个之前没有太涉及的领域,所以有必要把调研的过程和自己的一些理解纪录下来 为什么要自己定义过场动画? 假设大家有关注Materia ...
- Android 添加常驻图标到状态栏
/ * * 如果没有从状态栏中删除ICON,且继续调用addIconToStatusbar,则不会有任何变化.如果将notification中的resId设置不同的图标,则会显示不同的图标 * / p ...
- Android系统编译环境初始化时Product产品的import-nodes过程
从运行make -f config,mk文件開始,config,mk作为当前的makefile文件.将会被make解析,一般make解析Makefile文件流程首先是载入当中include的各种其它m ...
- OOA/OOD/OOP 转载
OOA/OOD/OOP OOA Object-Oriented Analysis:面向对象分析方法 是在一个系统的开发过程中进行了系统业务调查以后,按照面向对象的思想来分析问题.OOA与结构化分析有较 ...
- 谷歌AI中国中心成立,人工智能势不可挡?
昨日,谷歌在上海举办了一年一度的Google中国开发者大会.在本届大会上,谷歌云首席科学家李飞飞宣布了一个重磅消息,即在北京将成立谷歌AI中国中心.对于这个即将成立的AI中心谷歌寄予厚望,希望与中国本 ...