Commit 45f56c98 authored by Andreas Traczyk's avatar Andreas Traczyk

application: prevent multiple instances

Change-Id: Id7d28d66934d1c2eef893273d283ba5869a4a72a
parent f1df745f
......@@ -28,8 +28,6 @@
#include "media/text.h"
#include "media/file.h"
#include "globalinstances.h"
#include "pixbufmanipulator.h"
#include "lrcinstance.h"
#include <QTranslator>
#include <QLibraryInfo>
......@@ -37,7 +35,10 @@
#include <ciso646>
#include "lrcinstance.h"
#include "utils.h"
#include "runguard.h"
#include "pixbufmanipulator.h"
#ifdef Q_OS_WIN
#include <windows.h>
......@@ -103,6 +104,10 @@ fileDebug(QFile& debugFile)
int
main(int argc, char *argv[])
{
RunGuard guard("680b3e5eaf");
if (!guard.tryToRun())
return 0;
#ifdef Q_OS_WIN
SetProcessDPIAware();
#endif // Q_OS_WIN
......
......@@ -259,6 +259,7 @@
<ClCompile Include="regnamedialog.cpp" />
<ClCompile Include="ringbutton.cpp" />
<ClCompile Include="ringcontactlineedit.cpp" />
<ClCompile Include="runguard.cpp" />
<ClCompile Include="selectareadialog.cpp" />
<ClCompile Include="conversationsfilterwidget.cpp">
<OutputFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\%(Filename).moc</OutputFile>
......@@ -399,6 +400,7 @@
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\.;.\GeneratedFiles;.;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\lrc\src;$(ProjectDir)..\client-windows\winsparkle\include;$(ProjectDir)..\client-windows\qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release</IncludePath>
<Define Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;NIGHTLY_VERSION=20180706;ENABLE_AUTOUPDATE;QT_NO_DEBUG;NDEBUG</Define>
</QtMoc>
<ClInclude Include="runguard.h" />
<ClInclude Include="settingsitemwidget.h">
<IncludePath Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\.;.\GeneratedFiles;.;$(ProjectDir)..\daemon\contrib\msvc\include;$(ProjectDir)..\lrc\src;$(ProjectDir)..\client-windows\winsparkle\include;$(ProjectDir)..\client-windows\qrencode-win32\qrencode-win32;$(QTDIR)\include;$(QTDIR)\include\QtSvg;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtXml;$(QTDIR)\include\QtNetwork;$(QTDIR)\include\QtCore;$(QTDIR)\mkspecs\win32-msvc;.\release;$(QTDIR)\include\QtMultimedia;$(QTDIR)\include\QtMultimediaWidgets</IncludePath>
<Define Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;NIGHTLY_VERSION=20180706;ENABLE_AUTOUPDATE;QT_NO_DEBUG;NDEBUG;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB</Define>
......
......@@ -198,6 +198,9 @@
<ClCompile Include="newwizardwidget.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="runguard.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<QtMoc Include="aboutdialog.h">
......@@ -774,5 +777,8 @@
<ClInclude Include="version.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="runguard.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>
\ No newline at end of file
// From: https://stackoverflow.com/a/28172162
#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();
}
\ No newline at end of file
// From: https://stackoverflow.com/a/28172162
#pragma once
#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)
};
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment