Skip to content
Snippets Groups Projects
Commit 45f56c98 authored by Andreas Traczyk's avatar Andreas Traczyk
Browse files

application: prevent multiple instances

Change-Id: Id7d28d66934d1c2eef893273d283ba5869a4a72a
parent f1df745f
No related branches found
No related tags found
No related merge requests found
...@@ -28,8 +28,6 @@ ...@@ -28,8 +28,6 @@
#include "media/text.h" #include "media/text.h"
#include "media/file.h" #include "media/file.h"
#include "globalinstances.h" #include "globalinstances.h"
#include "pixbufmanipulator.h"
#include "lrcinstance.h"
#include <QTranslator> #include <QTranslator>
#include <QLibraryInfo> #include <QLibraryInfo>
...@@ -37,7 +35,10 @@ ...@@ -37,7 +35,10 @@
#include <ciso646> #include <ciso646>
#include "lrcinstance.h"
#include "utils.h" #include "utils.h"
#include "runguard.h"
#include "pixbufmanipulator.h"
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <windows.h> #include <windows.h>
...@@ -103,6 +104,10 @@ fileDebug(QFile& debugFile) ...@@ -103,6 +104,10 @@ fileDebug(QFile& debugFile)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
RunGuard guard("680b3e5eaf");
if (!guard.tryToRun())
return 0;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
SetProcessDPIAware(); SetProcessDPIAware();
#endif // Q_OS_WIN #endif // Q_OS_WIN
......
...@@ -259,6 +259,7 @@ ...@@ -259,6 +259,7 @@
<ClCompile Include="regnamedialog.cpp" /> <ClCompile Include="regnamedialog.cpp" />
<ClCompile Include="ringbutton.cpp" /> <ClCompile Include="ringbutton.cpp" />
<ClCompile Include="ringcontactlineedit.cpp" /> <ClCompile Include="ringcontactlineedit.cpp" />
<ClCompile Include="runguard.cpp" />
<ClCompile Include="selectareadialog.cpp" /> <ClCompile Include="selectareadialog.cpp" />
<ClCompile Include="conversationsfilterwidget.cpp"> <ClCompile Include="conversationsfilterwidget.cpp">
<OutputFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\%(Filename).moc</OutputFile> <OutputFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">.\GeneratedFiles\$(ConfigurationName)\%(Filename).moc</OutputFile>
...@@ -399,6 +400,7 @@ ...@@ -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> <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> <Define Condition="'$(Configuration)|$(Platform)'=='Release|x64'">_WINDOWS;UNICODE;_UNICODE;WIN32;WIN64;NIGHTLY_VERSION=20180706;ENABLE_AUTOUPDATE;QT_NO_DEBUG;NDEBUG</Define>
</QtMoc> </QtMoc>
<ClInclude Include="runguard.h" />
<ClInclude Include="settingsitemwidget.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> <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> <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 @@ ...@@ -198,6 +198,9 @@
<ClCompile Include="newwizardwidget.cpp"> <ClCompile Include="newwizardwidget.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="runguard.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<QtMoc Include="aboutdialog.h"> <QtMoc Include="aboutdialog.h">
...@@ -774,5 +777,8 @@ ...@@ -774,5 +777,8 @@
<ClInclude Include="version.h"> <ClInclude Include="version.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="runguard.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment