reliably kill dbus-daemon and kdeconnect-daemon using WinAPIs
This commit is contained in:
parent
28b7ad0a5d
commit
06d81412b6
3 changed files with 99 additions and 4 deletions
|
@ -16,6 +16,14 @@
|
||||||
#include <KStatusNotifierItem>
|
#include <KStatusNotifierItem>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include <QUrl>
|
||||||
|
namespace processes {
|
||||||
|
const QString dbus_daemon = QStringLiteral("dbus-daemon.exe");
|
||||||
|
const QString kdeconnect_daemon = QStringLiteral("kdeconnectd.exe");
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
class IndicatorHelper
|
class IndicatorHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -35,6 +43,16 @@ public:
|
||||||
void systrayIconHook(KStatusNotifierItem &systray);
|
void systrayIconHook(KStatusNotifierItem &systray);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
/**
|
||||||
|
* Terminate processes of KDE Connect like kdeconnectd.exe and dbus-daemon.exe
|
||||||
|
*
|
||||||
|
* @return True if termination was successful, false otherwise
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool terminateProcess(const QString &processName, const QUrl &indicatorUrl) const;
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
QSplashScreen *m_splashScreen;
|
QSplashScreen *m_splashScreen;
|
||||||
|
|
|
@ -7,8 +7,15 @@
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QIcon>
|
#include <QIcon>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <tlhelp32.h>
|
||||||
|
|
||||||
#include "indicatorhelper.h"
|
#include "indicatorhelper.h"
|
||||||
|
#include "indicator_debug.h"
|
||||||
|
|
||||||
IndicatorHelper::IndicatorHelper() {}
|
IndicatorHelper::IndicatorHelper() {}
|
||||||
IndicatorHelper::~IndicatorHelper() {}
|
IndicatorHelper::~IndicatorHelper() {}
|
||||||
|
@ -21,7 +28,7 @@ void IndicatorHelper::iconPathHook() {}
|
||||||
|
|
||||||
int IndicatorHelper::daemonHook(QProcess &kdeconnectd)
|
int IndicatorHelper::daemonHook(QProcess &kdeconnectd)
|
||||||
{
|
{
|
||||||
kdeconnectd.start(QStringLiteral("kdeconnectd.exe"));
|
kdeconnectd.start(processes::kdeconnect_daemon);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,3 +43,65 @@ void IndicatorHelper::systrayIconHook(KStatusNotifierItem &systray)
|
||||||
Q_UNUSED(systray);
|
Q_UNUSED(systray);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool IndicatorHelper::terminateProcess(const QString &processName, const QUrl &indicatorUrl) const
|
||||||
|
{
|
||||||
|
HANDLE hProcessSnap;
|
||||||
|
HANDLE hProcess;
|
||||||
|
|
||||||
|
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||||
|
if (hProcessSnap == INVALID_HANDLE_VALUE) {
|
||||||
|
qCWarning(KDECONNECT_INDICATOR) << "Failed to get snapshot of processes.";
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESSENTRY32 pe32;
|
||||||
|
pe32.dwSize = sizeof(PROCESSENTRY32);
|
||||||
|
|
||||||
|
if (!Process32First(hProcessSnap, &pe32)) {
|
||||||
|
qCWarning(KDECONNECT_INDICATOR) << "Failed to get handle for the first process.";
|
||||||
|
CloseHandle(hProcessSnap);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (QString::fromWCharArray(pe32.szExeFile) == processName) {
|
||||||
|
hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
|
||||||
|
|
||||||
|
if (hProcess == NULL) {
|
||||||
|
qCWarning(KDECONNECT_INDICATOR) << "Failed to get handle for the process:" << processName;
|
||||||
|
return FALSE;
|
||||||
|
} else {
|
||||||
|
const DWORD processPathSize = 4096;
|
||||||
|
CHAR processPathString[processPathSize];
|
||||||
|
|
||||||
|
BOOL gotProcessPath = QueryFullProcessImageNameA(
|
||||||
|
hProcess,
|
||||||
|
0,
|
||||||
|
(LPSTR)processPathString,
|
||||||
|
(PDWORD) &processPathSize
|
||||||
|
);
|
||||||
|
|
||||||
|
if (gotProcessPath) {
|
||||||
|
const QUrl processUrl = QUrl::fromLocalFile(QString::fromStdString(processPathString)); // to replace \\ with /
|
||||||
|
if (indicatorUrl.isParentOf(processUrl)) {
|
||||||
|
BOOL terminateSuccess = TerminateProcess(
|
||||||
|
hProcess,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
if (!terminateSuccess) {
|
||||||
|
qCWarning(KDECONNECT_INDICATOR) << "Failed to terminate process:" << processName;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (Process32Next(hProcessSnap, &pe32));
|
||||||
|
|
||||||
|
CloseHandle(hProcessSnap);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ int main(int argc, char** argv)
|
||||||
QMenu* menu = new QMenu;
|
QMenu* menu = new QMenu;
|
||||||
|
|
||||||
DaemonDbusInterface iface;
|
DaemonDbusInterface iface;
|
||||||
auto refreshMenu = [&iface, &model, &menu]() {
|
auto refreshMenu = [&iface, &model, &menu, &helper]() {
|
||||||
menu->clear();
|
menu->clear();
|
||||||
auto configure = menu->addAction(QIcon::fromTheme(QStringLiteral("configure")), i18n("Configure..."));
|
auto configure = menu->addAction(QIcon::fromTheme(QStringLiteral("configure")), i18n("Configure..."));
|
||||||
QObject::connect(configure, &QAction::triggered, configure, [](){
|
QObject::connect(configure, &QAction::triggered, configure, [](){
|
||||||
|
@ -83,9 +83,9 @@ int main(int argc, char** argv)
|
||||||
pairMenu->addAction(i18n("Reject"), dev, &DeviceDbusInterface::rejectPairing);
|
pairMenu->addAction(i18n("Reject"), dev, &DeviceDbusInterface::rejectPairing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (defined Q_OS_MAC || defined Q_OS_WIN)
|
|
||||||
// Add quit menu
|
// Add quit menu
|
||||||
|
#if defined Q_OS_MAC
|
||||||
|
|
||||||
menu->addAction(i18n("Quit"), [](){
|
menu->addAction(i18n("Quit"), [](){
|
||||||
auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect.daemon"),
|
auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect.daemon"),
|
||||||
QStringLiteral("/MainApplication"),
|
QStringLiteral("/MainApplication"),
|
||||||
|
@ -98,6 +98,14 @@ int main(int argc, char** argv)
|
||||||
QStringLiteral("quit"));
|
QStringLiteral("quit"));
|
||||||
DBusHelper::sessionBus().call(message, QDBus::NoBlock); // Close our indicator
|
DBusHelper::sessionBus().call(message, QDBus::NoBlock); // Close our indicator
|
||||||
});
|
});
|
||||||
|
#elif defined Q_OS_WIN
|
||||||
|
|
||||||
|
menu->addAction(i18n("Quit"), [&helper](){
|
||||||
|
const QUrl indicatorUrl = QUrl::fromLocalFile(qApp->applicationDirPath());
|
||||||
|
helper.terminateProcess(processes::dbus_daemon, indicatorUrl);
|
||||||
|
helper.terminateProcess(processes::kdeconnect_daemon, indicatorUrl);
|
||||||
|
qApp->quit();
|
||||||
|
});
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue