mirror of
https://github.com/qbittorrent/qBittorrent
synced 2025-07-14 01:03:08 -07:00
Use unmodified QtSingleApplication on Windows.
Get running application instance PID without QtSingleApplication modification.
This commit is contained in:
parent
e52a8fb0b0
commit
2dd473eb28
7 changed files with 47 additions and 89 deletions
|
@ -32,6 +32,10 @@
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
#include <QSysInfo>
|
#include <QSysInfo>
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <QSharedMemory>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if (!defined(DISABLE_GUI) && defined(Q_OS_MAC))
|
#if (!defined(DISABLE_GUI) && defined(Q_OS_MAC))
|
||||||
#include <QFont>
|
#include <QFont>
|
||||||
|
@ -41,11 +45,7 @@
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
|
|
||||||
Application::Application(const QString &id, int &argc, char **argv)
|
Application::Application(const QString &id, int &argc, char **argv)
|
||||||
#ifndef DISABLE_GUI
|
: BaseApplication(id, argc, argv)
|
||||||
: SessionApplication(id, argc, argv)
|
|
||||||
#else
|
|
||||||
: QtSingleCoreApplication(id, argc, argv)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
#if defined(Q_OS_MACX) && !defined(DISABLE_GUI)
|
#if defined(Q_OS_MACX) && !defined(DISABLE_GUI)
|
||||||
if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_8) {
|
if (QSysInfo::MacintoshVersion > QSysInfo::MV_10_8) {
|
||||||
|
@ -62,6 +62,33 @@ Application::Application(const QString &id, int &argc, char **argv)
|
||||||
#endif
|
#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()
|
void Application::initializeTranslation()
|
||||||
{
|
{
|
||||||
Preferences* const pref = Preferences::instance();
|
Preferences* const pref = Preferences::instance();
|
||||||
|
@ -72,10 +99,10 @@ void Application::initializeTranslation()
|
||||||
pref->setLocale(locale);
|
pref->setLocale(locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qtTranslator_.load(
|
if (m_qtTranslator.load(
|
||||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
|
#if (QT_VERSION >= QT_VERSION_CHECK(5, 0, 0))
|
||||||
QString::fromUtf8("qtbase_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)) ||
|
QString::fromUtf8("qtbase_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath)) ||
|
||||||
qtTranslator_.load(
|
m_qtTranslator.load(
|
||||||
#endif
|
#endif
|
||||||
QString::fromUtf8("qt_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
|
QString::fromUtf8("qt_") + locale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) {
|
||||||
qDebug("Qt %s locale recognized, using translation.", qPrintable(locale));
|
qDebug("Qt %s locale recognized, using translation.", qPrintable(locale));
|
||||||
|
@ -83,15 +110,15 @@ void Application::initializeTranslation()
|
||||||
else {
|
else {
|
||||||
qDebug("Qt %s locale unrecognized, using default (en).", qPrintable(locale));
|
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));
|
qDebug("%s locale recognized, using translation.", qPrintable(locale));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
qDebug("%s locale unrecognized, using default (en).", qPrintable(locale));
|
qDebug("%s locale unrecognized, using default (en).", qPrintable(locale));
|
||||||
}
|
}
|
||||||
installTranslator(&translator_);
|
installTranslator(&m_translator);
|
||||||
|
|
||||||
#ifndef DISABLE_GUI
|
#ifndef DISABLE_GUI
|
||||||
if (locale.startsWith("ar") || locale.startsWith("he")) {
|
if (locale.startsWith("ar") || locale.startsWith("he")) {
|
||||||
|
|
|
@ -35,23 +35,24 @@
|
||||||
|
|
||||||
#ifndef DISABLE_GUI
|
#ifndef DISABLE_GUI
|
||||||
#include "sessionapplication.h"
|
#include "sessionapplication.h"
|
||||||
|
typedef SessionApplication BaseApplication;
|
||||||
#else
|
#else
|
||||||
#include "qtsinglecoreapplication.h"
|
#include "qtsinglecoreapplication.h"
|
||||||
|
typedef QtSingleCoreApplication BaseApplication;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Application
|
class Application : public BaseApplication
|
||||||
#ifndef DISABLE_GUI
|
|
||||||
: public SessionApplication
|
|
||||||
#else
|
|
||||||
: public QtSingleCoreApplication
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Application(const QString &id, int &argc, char **argv);
|
Application(const QString &id, int &argc, char **argv);
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
bool isRunning();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTranslator qtTranslator_;
|
QTranslator m_qtTranslator;
|
||||||
QTranslator translator_;
|
QTranslator m_translator;
|
||||||
|
|
||||||
void initializeTranslation();
|
void initializeTranslation();
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,10 +90,6 @@ public:
|
||||||
|
|
||||||
#include "main.moc"
|
#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
|
// Signal handlers
|
||||||
#if defined(Q_OS_UNIX) || defined(STACKTRACE_WIN)
|
#if defined(Q_OS_UNIX) || defined(STACKTRACE_WIN)
|
||||||
void sigintHandler(int);
|
void sigintHandler(int);
|
||||||
|
@ -217,14 +213,8 @@ int main(int argc, char *argv[])
|
||||||
#else
|
#else
|
||||||
qDebug("qBittorrent is already running for this user.");
|
qDebug("qBittorrent is already running for this user.");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
misc::msleep(300);
|
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()) {
|
if (!params.torrents.isEmpty()) {
|
||||||
QString message = params.torrents.join("|");
|
QString message = params.torrents.join("|");
|
||||||
qDebug("Passing program parameters to running instance...");
|
qDebug("Passing program parameters to running instance...");
|
||||||
|
|
|
@ -195,56 +195,9 @@ void QtLocalPeer::receiveConnection()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QString message(QString::fromUtf8(uMsg));
|
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));
|
socket->write(ack, qstrlen(ack));
|
||||||
#endif
|
|
||||||
socket->waitForBytesWritten(1000);
|
socket->waitForBytesWritten(1000);
|
||||||
socket->waitForDisconnected(1000); // make sure client reads ack
|
socket->waitForDisconnected(1000); // make sure client reads ack
|
||||||
delete socket;
|
delete socket;
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if (message == "qbt://pid")
|
|
||||||
return;
|
|
||||||
#endif
|
|
||||||
emit messageReceived(message); //### (might take a long time to return)
|
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
|
|
||||||
|
|
|
@ -57,9 +57,6 @@ public:
|
||||||
bool sendMessage(const QString &message, int timeout);
|
bool sendMessage(const QString &message, int timeout);
|
||||||
QString applicationId() const
|
QString applicationId() const
|
||||||
{ return id; }
|
{ return id; }
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
qint64 getRunningPid();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void messageReceived(const QString &message);
|
void messageReceived(const QString &message);
|
||||||
|
|
|
@ -345,9 +345,3 @@ void QtSingleApplication::activateWindow()
|
||||||
|
|
||||||
\obsolete
|
\obsolete
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
qint64 QtSingleApplication::getRunningPid() {
|
|
||||||
return peer->getRunningPid();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -86,10 +86,6 @@ public:
|
||||||
// Obsolete:
|
// Obsolete:
|
||||||
void initialize(bool dummy = true)
|
void initialize(bool dummy = true)
|
||||||
{ isRunning(); Q_UNUSED(dummy) }
|
{ isRunning(); Q_UNUSED(dummy) }
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
#define QBT_HAS_GETCURRENTPID
|
|
||||||
qint64 getRunningPid();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
bool sendMessage(const QString &message, int timeout = 5000);
|
bool sendMessage(const QString &message, int timeout = 5000);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue