Browse Source

Use unmodified QtSingleApplication on Windows.

Get running application instance PID without QtSingleApplication
modification.
adaptive-webui-19844
Vladimir Golovnev (Glassez) 10 years ago
parent
commit
2dd473eb28
  1. 47
      src/app/application.cpp
  2. 17
      src/app/application.h
  3. 12
      src/app/main.cpp
  4. 47
      src/app/qtsingleapplication/qtlocalpeer.cpp
  5. 3
      src/app/qtsingleapplication/qtlocalpeer.h
  6. 6
      src/app/qtsingleapplication/qtsingleapplication.cpp
  7. 4
      src/app/qtsingleapplication/qtsingleapplication.h

47
src/app/application.cpp

@ -32,6 +32,10 @@ @@ -32,6 +32,10 @@
#include <QLocale>
#include <QLibraryInfo>
#include <QSysInfo>
#ifdef Q_OS_WIN
#include <Windows.h>
#include <QSharedMemory>
#endif
#if (!defined(DISABLE_GUI) && defined(Q_OS_MAC))
#include <QFont>
@ -41,11 +45,7 @@ @@ -41,11 +45,7 @@
#include "preferences.h"
Application::Application(const QString &id, int &argc, char **argv)
#ifndef DISABLE_GUI
: SessionApplication(id, argc, argv)
#else
: QtSingleCoreApplication(id, argc, argv)
#endif
: BaseApplication(id, argc, argv)
{
#if defined(Q_OS_MACX) && !defined(DISABLE_GUI)
if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_8) {
@ -62,6 +62,33 @@ Application::Application(const QString &id, int &argc, char **argv) @@ -62,6 +62,33 @@ Application::Application(const QString &id, int &argc, char **argv)
#endif
}
#ifdef Q_OS_WIN
bool Application::isRunning()
{
bool running = BaseApplication::isRunning();
QSharedMemory *sharedMem = new QSharedMemory(id() + QLatin1String("-shared-memory-key"), this);
if (!running) {
// First instance creates shared memory and store PID
if (sharedMem->create(sizeof(DWORD)) && sharedMem->lock()) {
*(static_cast<DWORD*>(sharedMem->data())) = ::GetCurrentProcessId();
sharedMem->unlock();
}
}
else {
// Later instances attach to shared memory and retrieve PID
if (sharedMem->attach() && sharedMem->lock()) {
::AllowSetForegroundWindow(*(static_cast<DWORD*>(sharedMem->data())));
sharedMem->unlock();
}
}
if (!sharedMem->isAttached())
qWarning() << "Failed to initialize shared memory: " << sharedMem->errorString();
return running;
}
#endif
void Application::initializeTranslation()
{
Preferences* const pref = Preferences::instance();
@ -72,10 +99,10 @@ void Application::initializeTranslation() @@ -72,10 +99,10 @@ void Application::initializeTranslation()
pref->setLocale(locale);
}
if (qtTranslator_.load(
if (m_qtTranslator.load(
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
QString::fromUtf8("qtbase_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)) ||
qtTranslator_.load(
m_qtTranslator.load(
#endif
QString::fromUtf8("qt_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
qDebug("Qt %s locale recognized, using translation.", qPrintable(locale));
@ -83,15 +110,15 @@ void Application::initializeTranslation() @@ -83,15 +110,15 @@ void Application::initializeTranslation()
else {
qDebug("Qt %s locale unrecognized, using default (en).", qPrintable(locale));
}
installTranslator(&qtTranslator_);
installTranslator(&m_qtTranslator);
if (translator_.load(QString::fromUtf8(":/lang/qbittorrent_") + locale)) {
if (m_translator.load(QString::fromUtf8(":/lang/qbittorrent_") + locale)) {
qDebug("%s locale recognized, using translation.", qPrintable(locale));
}
else {
qDebug("%s locale unrecognized, using default (en).", qPrintable(locale));
}
installTranslator(&translator_);
installTranslator(&m_translator);
#ifndef DISABLE_GUI
if (locale.startsWith("ar") || locale.startsWith("he")) {

17
src/app/application.h

@ -35,23 +35,24 @@ @@ -35,23 +35,24 @@
#ifndef DISABLE_GUI
#include "sessionapplication.h"
typedef SessionApplication BaseApplication;
#else
#include "qtsinglecoreapplication.h"
typedef QtSingleCoreApplication BaseApplication;
#endif
class Application
#ifndef DISABLE_GUI
: public SessionApplication
#else
: public QtSingleCoreApplication
#endif
class Application : public BaseApplication
{
public:
Application(const QString &id, int &argc, char **argv);
#ifdef Q_OS_WIN
bool isRunning();
#endif
private:
QTranslator qtTranslator_;
QTranslator translator_;
QTranslator m_qtTranslator;
QTranslator m_translator;
void initializeTranslation();
};

12
src/app/main.cpp

@ -90,10 +90,6 @@ public: @@ -90,10 +90,6 @@ public:
#include "main.moc"
#if defined(Q_OS_WIN) && !defined(QBT_HAS_GETCURRENTPID)
#error You seem to have updated QtSingleApplication without porting our custom QtSingleApplication::getRunningPid() function. Please see previous version to understate how it works.
#endif
// Signal handlers
#if defined(Q_OS_UNIX) || defined(STACKTRACE_WIN)
void sigintHandler(int);
@ -217,14 +213,8 @@ int main(int argc, char *argv[]) @@ -217,14 +213,8 @@ int main(int argc, char *argv[])
#else
qDebug("qBittorrent is already running for this user.");
#endif
misc::msleep(300);
#ifdef Q_OS_WIN
DWORD pid = (DWORD)app->getRunningPid();
if (pid > 0) {
BOOL b = AllowSetForegroundWindow(pid);
qDebug("AllowSetForegroundWindow() returns %s", b ? "TRUE" : "FALSE");
}
#endif
if (!params.torrents.isEmpty()) {
QString message = params.torrents.join("|");
qDebug("Passing program parameters to running instance...");

47
src/app/qtsingleapplication/qtlocalpeer.cpp

@ -195,56 +195,9 @@ void QtLocalPeer::receiveConnection() @@ -195,56 +195,9 @@ void QtLocalPeer::receiveConnection()
return;
}
QString message(QString::fromUtf8(uMsg));
#ifdef Q_OS_WIN
if (message == "qbt://pid") {
qint64 pid = GetCurrentProcessId();
socket->write((const char *)&pid, sizeof pid);
} else {
socket->write(ack, qstrlen(ack));
}
#else
socket->write(ack, qstrlen(ack));
#endif
socket->waitForBytesWritten(1000);
socket->waitForDisconnected(1000); // make sure client reads ack
delete socket;
#ifdef Q_OS_WIN
if (message == "qbt://pid")
return;
#endif
emit messageReceived(message); //### (might take a long time to return)
}
#ifdef Q_OS_WIN
qint64 QtLocalPeer::getRunningPid() {
if (!isClient())
return 0;
QLocalSocket socket;
bool connOk = false;
for (int i = 0; i < 2; i++) {
// Try twice, in case the other instance is just starting up
socket.connectToServer(socketName);
connOk = socket.waitForConnected(5000/2);
if (connOk || i)
break;
Sleep(250);
}
if (!connOk) return -1;
const char* msg = "qbt://pid";
QDataStream ds(&socket);
ds.writeBytes(msg, qstrlen(msg));
bool res = socket.waitForBytesWritten(5000) && socket.waitForReadyRead(5000);
if (!res) return -1;
DWORD pid;
qint64 pid_size = sizeof pid;
while (socket.bytesAvailable() < pid_size)
socket.waitForReadyRead();
if (socket.read((char *)&pid, pid_size) < pid_size)
return -1;
return pid;
}
#endif

3
src/app/qtsingleapplication/qtlocalpeer.h

@ -57,9 +57,6 @@ public: @@ -57,9 +57,6 @@ public:
bool sendMessage(const QString &message, int timeout);
QString applicationId() const
{ return id; }
#ifdef Q_OS_WIN
qint64 getRunningPid();
#endif
Q_SIGNALS:
void messageReceived(const QString &message);

6
src/app/qtsingleapplication/qtsingleapplication.cpp

@ -345,9 +345,3 @@ void QtSingleApplication::activateWindow() @@ -345,9 +345,3 @@ void QtSingleApplication::activateWindow()
\obsolete
*/
#ifdef Q_OS_WIN
qint64 QtSingleApplication::getRunningPid() {
return peer->getRunningPid();
}
#endif

4
src/app/qtsingleapplication/qtsingleapplication.h

@ -86,10 +86,6 @@ public: @@ -86,10 +86,6 @@ public:
// Obsolete:
void initialize(bool dummy = true)
{ isRunning(); Q_UNUSED(dummy) }
#ifdef Q_OS_WIN
#define QBT_HAS_GETCURRENTPID
qint64 getRunningPid();
#endif
public Q_SLOTS:
bool sendMessage(const QString &message, int timeout = 5000);

Loading…
Cancel
Save