mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-27 19:24:08 +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
|
LIBS += -lvorbisfile -lvorbis -logg -lz -lzip -lhunspell
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
LIBS += -liconv -lwsock32 -lwinmm
|
LIBS += -liconv -lwsock32 -lwinmm -lpsapi
|
||||||
RC_FILE = goldendict.rc
|
RC_FILE = goldendict.rc
|
||||||
INCLUDEPATH += winlibs/include
|
INCLUDEPATH += winlibs/include
|
||||||
LIBS += -Lwinlibs/lib
|
LIBS += -Lwinlibs/lib
|
||||||
|
@ -94,7 +94,8 @@ HEADERS += folding.hh \
|
||||||
dictdfiles.hh \
|
dictdfiles.hh \
|
||||||
audiolink.hh \
|
audiolink.hh \
|
||||||
wstring.hh \
|
wstring.hh \
|
||||||
wstring_qt.hh
|
wstring_qt.hh \
|
||||||
|
processwrapper.hh
|
||||||
|
|
||||||
|
|
||||||
FORMS += groups.ui dictgroupwidget.ui mainwindow.ui sources.ui initializing.ui\
|
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 \
|
articleview.cc externalviewer.cc wordfinder.cc \
|
||||||
groupcombobox.cc keyboardstate.cc mouseover.cc preferences.cc \
|
groupcombobox.cc keyboardstate.cc mouseover.cc preferences.cc \
|
||||||
mutex.cc mediawiki.cc sounddir.cc hunspell.cc dictdfiles.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 {
|
win32 {
|
||||||
SOURCES += mouseover_win32/ThTypes.c
|
SOURCES += mouseover_win32/ThTypes.c
|
||||||
|
|
23
src/main.cc
23
src/main.cc
|
@ -5,6 +5,7 @@
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include "mainwindow.hh"
|
#include "mainwindow.hh"
|
||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
|
#include "processwrapper.hh"
|
||||||
|
|
||||||
//#define __DO_DEBUG
|
//#define __DO_DEBUG
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ int main( int argc, char ** argv )
|
||||||
#ifdef __DO_DEBUG
|
#ifdef __DO_DEBUG
|
||||||
{
|
{
|
||||||
rlimit limit;
|
rlimit limit;
|
||||||
|
|
||||||
memset( &limit, 0, sizeof( limit ) );
|
memset( &limit, 0, sizeof( limit ) );
|
||||||
limit.rlim_cur = RLIM_INFINITY;
|
limit.rlim_cur = RLIM_INFINITY;
|
||||||
limit.rlim_max = RLIM_INFINITY;
|
limit.rlim_max = RLIM_INFINITY;
|
||||||
|
@ -34,6 +35,20 @@ int main( int argc, char ** argv )
|
||||||
|
|
||||||
Config::Class cfg( Config::load() );
|
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
|
// Load translations
|
||||||
|
|
||||||
QTranslator qtTranslator;
|
QTranslator qtTranslator;
|
||||||
|
@ -58,13 +73,13 @@ int main( int argc, char ** argv )
|
||||||
QFile builtInCssFile( ":/qt-style.css" );
|
QFile builtInCssFile( ":/qt-style.css" );
|
||||||
builtInCssFile.open( QFile::ReadOnly );
|
builtInCssFile.open( QFile::ReadOnly );
|
||||||
QByteArray css = builtInCssFile.readAll();
|
QByteArray css = builtInCssFile.readAll();
|
||||||
|
|
||||||
// Try loading a style sheet if there's one
|
// Try loading a style sheet if there's one
|
||||||
QFile cssFile( Config::getUserQtCssFileName() );
|
QFile cssFile( Config::getUserQtCssFileName() );
|
||||||
|
|
||||||
if ( cssFile.open( QFile::ReadOnly ) )
|
if ( cssFile.open( QFile::ReadOnly ) )
|
||||||
css += cssFile.readAll();
|
css += cssFile.readAll();
|
||||||
|
|
||||||
app.setStyleSheet( css );
|
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