mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 15:24:05 +00:00
+ Prevent a second copy of a program from running (patch by Ars)
This commit is contained in:
parent
f0a553a6b6
commit
abc7d564b2
|
@ -22,7 +22,7 @@ RCC_DIR = build
|
|||
LIBS += -lvorbisfile -lvorbis -logg -lz -lzip -lhunspell
|
||||
|
||||
win32 {
|
||||
LIBS += -liconv -lwsock32 -lwinmm
|
||||
LIBS += -liconv -lwsock32 -lwinmm -lpsapi
|
||||
RC_FILE = goldendict.rc
|
||||
INCLUDEPATH += winlibs/include
|
||||
LIBS += -Lwinlibs/lib
|
||||
|
@ -94,7 +94,8 @@ HEADERS += folding.hh \
|
|||
dictdfiles.hh \
|
||||
audiolink.hh \
|
||||
wstring.hh \
|
||||
wstring_qt.hh
|
||||
wstring_qt.hh \
|
||||
processwrapper.hh
|
||||
|
||||
|
||||
FORMS += groups.ui dictgroupwidget.ui mainwindow.ui sources.ui initializing.ui\
|
||||
|
@ -110,7 +111,7 @@ SOURCES += folding.cc main.cc dictionary.cc config.cc sources.cc \
|
|||
articleview.cc externalviewer.cc wordfinder.cc \
|
||||
groupcombobox.cc keyboardstate.cc mouseover.cc preferences.cc \
|
||||
mutex.cc mediawiki.cc sounddir.cc hunspell.cc dictdfiles.cc \
|
||||
audiolink.cc wstring.cc wstring_qt.cc
|
||||
audiolink.cc wstring.cc wstring_qt.cc processwrapper.cc
|
||||
|
||||
win32 {
|
||||
SOURCES += mouseover_win32/ThTypes.c
|
||||
|
|
23
src/main.cc
23
src/main.cc
|
@ -5,6 +5,7 @@
|
|||
#include <QIcon>
|
||||
#include "mainwindow.hh"
|
||||
#include "config.hh"
|
||||
#include "processwrapper.hh"
|
||||
|
||||
//#define __DO_DEBUG
|
||||
|
||||
|
@ -17,7 +18,7 @@ int main( int argc, char ** argv )
|
|||
#ifdef __DO_DEBUG
|
||||
{
|
||||
rlimit limit;
|
||||
|
||||
|
||||
memset( &limit, 0, sizeof( limit ) );
|
||||
limit.rlim_cur = RLIM_INFINITY;
|
||||
limit.rlim_max = RLIM_INFINITY;
|
||||
|
@ -34,6 +35,20 @@ int main( int argc, char ** argv )
|
|||
|
||||
Config::Class cfg( Config::load() );
|
||||
|
||||
|
||||
// Prevent execution of the 2nd copy
|
||||
|
||||
// check if 2nd copy was started
|
||||
QString app_fname = QFileInfo(QCoreApplication::applicationFilePath()).baseName();
|
||||
unsigned int pid = ProcessWrapper::findProcess(
|
||||
app_fname.toAscii().data(),
|
||||
QCoreApplication::applicationPid());
|
||||
if (pid)
|
||||
{
|
||||
// to do: switch to pid ?
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Load translations
|
||||
|
||||
QTranslator qtTranslator;
|
||||
|
@ -58,13 +73,13 @@ int main( int argc, char ** argv )
|
|||
QFile builtInCssFile( ":/qt-style.css" );
|
||||
builtInCssFile.open( QFile::ReadOnly );
|
||||
QByteArray css = builtInCssFile.readAll();
|
||||
|
||||
|
||||
// Try loading a style sheet if there's one
|
||||
QFile cssFile( Config::getUserQtCssFileName() );
|
||||
|
||||
|
||||
if ( cssFile.open( QFile::ReadOnly ) )
|
||||
css += cssFile.readAll();
|
||||
|
||||
|
||||
app.setStyleSheet( css );
|
||||
}
|
||||
|
||||
|
|
115
src/processwrapper.cc
Normal file
115
src/processwrapper.cc
Normal file
|
@ -0,0 +1,115 @@
|
|||
#include "processwrapper.hh"
|
||||
|
||||
#include <QtCore>
|
||||
|
||||
#ifdef Q_OS_WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <psapi.h>
|
||||
|
||||
unsigned int ProcessWrapper::currentProcessId()
|
||||
{
|
||||
return GetCurrentProcessId();
|
||||
}
|
||||
|
||||
unsigned int ProcessWrapper::findProcess(const char *name, unsigned int pid_skip)
|
||||
{
|
||||
DWORD aProcesses[1024], cbNeeded, cProcesses;
|
||||
unsigned int i;
|
||||
QString pname(name); pname += ".exe";
|
||||
|
||||
if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
|
||||
return 0;
|
||||
|
||||
// Calculate how many process identifiers were returned.
|
||||
|
||||
cProcesses = cbNeeded / sizeof(DWORD);
|
||||
|
||||
// Print the name and process identifier for each process.
|
||||
|
||||
for ( i = 0; i < cProcesses; i++ )
|
||||
{
|
||||
unsigned int processID = aProcesses[i];
|
||||
if( processID != 0 && processID != pid_skip )
|
||||
{
|
||||
char szProcessName[MAX_PATH] = "<unknown>";
|
||||
|
||||
// Get a handle to the process.
|
||||
|
||||
HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
|
||||
PROCESS_VM_READ,
|
||||
FALSE, processID );
|
||||
|
||||
// Get the process name.
|
||||
|
||||
if (NULL != hProcess )
|
||||
{
|
||||
HMODULE hMod;
|
||||
DWORD cbNeeded;
|
||||
|
||||
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
|
||||
&cbNeeded) )
|
||||
{
|
||||
GetModuleBaseNameA( hProcess, hMod, szProcessName,
|
||||
sizeof(szProcessName)/sizeof(TCHAR) );
|
||||
|
||||
if (QString(szProcessName) == pname) {
|
||||
CloseHandle( hProcess );
|
||||
return processID;
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle( hProcess );
|
||||
}
|
||||
|
||||
// Print the process name and identifier.
|
||||
|
||||
//_tprintf( TEXT("%s (PID: %u)\n"), szProcessName, processID );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
unsigned int ProcessWrapper::currentProcessId()
|
||||
{
|
||||
return getpid();
|
||||
}
|
||||
|
||||
unsigned int ProcessWrapper::findProcess(const char *name, unsigned int pid_skip)
|
||||
{
|
||||
QString pname("(" + QString(name) + ")");
|
||||
QDir pd("/proc");
|
||||
QFileInfoList list = pd.entryInfoList(QDir::Dirs | QDir::NoSymLinks | QDir::NoDotAndDotDot);
|
||||
QFileInfoList::iterator it, it_end = list.end();
|
||||
for (it = list.begin(); it != it_end; it++)
|
||||
{
|
||||
const QFileInfo &fi = *it;
|
||||
if (fi.baseName().at(0).isDigit()) {
|
||||
QFile f(fi.absoluteFilePath()+"/stat");
|
||||
if (f.open(QIODevice::ReadOnly)) {
|
||||
QTextStream ts(&f);
|
||||
unsigned int pid; ts >> pid;
|
||||
if (pid == pid_skip)
|
||||
continue;
|
||||
QString pn; ts >> pn;
|
||||
if (pn == pname)
|
||||
return pid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
ProcessWrapper::ProcessWrapper()
|
||||
{
|
||||
}
|
||||
|
13
src/processwrapper.hh
Normal file
13
src/processwrapper.hh
Normal file
|
@ -0,0 +1,13 @@
|
|||
#ifndef PROCESSWRAPPER_H
|
||||
#define PROCESSWRAPPER_H
|
||||
|
||||
class ProcessWrapper
|
||||
{
|
||||
public:
|
||||
ProcessWrapper();
|
||||
|
||||
static unsigned int findProcess(const char *name, unsigned int pid_skip = 0);
|
||||
static unsigned int currentProcessId();
|
||||
};
|
||||
|
||||
#endif // PROCESSWRAPPER_H
|
Loading…
Reference in a new issue