mirror of
https://github.com/d47081/qBittorrent.git
synced 2025-01-11 07:18:08 +00:00
Use unmodified QtSingleApplication on Windows.
Get running application instance PID without QtSingleApplication modification.
This commit is contained in:
parent
e52a8fb0b0
commit
2dd473eb28
@ -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 @@
|
||||
#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)
|
||||
#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()
|
||||
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()
|
||||
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")) {
|
||||
|
@ -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();
|
||||
};
|
||||
|
@ -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[])
|
||||
#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...");
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -345,9 +345,3 @@ void QtSingleApplication::activateWindow()
|
||||
|
||||
\obsolete
|
||||
*/
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
qint64 QtSingleApplication::getRunningPid() {
|
||||
return peer->getRunningPid();
|
||||
}
|
||||
#endif
|
||||
|
@ -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…
Reference in New Issue
Block a user