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>
|
||||
#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
|
||||
{
|
||||
public:
|
||||
|
@ -35,6 +43,16 @@ public:
|
|||
void systrayIconHook(KStatusNotifierItem &systray);
|
||||
#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:
|
||||
#ifdef Q_OS_MAC
|
||||
QSplashScreen *m_splashScreen;
|
||||
|
|
|
@ -7,8 +7,15 @@
|
|||
#include <QFile>
|
||||
#include <QIcon>
|
||||
#include <QStandardPaths>
|
||||
#include <QDebug>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <Windows.h>
|
||||
#include <tlhelp32.h>
|
||||
|
||||
#include "indicatorhelper.h"
|
||||
#include "indicator_debug.h"
|
||||
|
||||
IndicatorHelper::IndicatorHelper() {}
|
||||
IndicatorHelper::~IndicatorHelper() {}
|
||||
|
@ -21,7 +28,7 @@ void IndicatorHelper::iconPathHook() {}
|
|||
|
||||
int IndicatorHelper::daemonHook(QProcess &kdeconnectd)
|
||||
{
|
||||
kdeconnectd.start(QStringLiteral("kdeconnectd.exe"));
|
||||
kdeconnectd.start(processes::kdeconnect_daemon);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -36,3 +43,65 @@ void IndicatorHelper::systrayIconHook(KStatusNotifierItem &systray)
|
|||
Q_UNUSED(systray);
|
||||
}
|
||||
#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;
|
||||
|
||||
DaemonDbusInterface iface;
|
||||
auto refreshMenu = [&iface, &model, &menu]() {
|
||||
auto refreshMenu = [&iface, &model, &menu, &helper]() {
|
||||
menu->clear();
|
||||
auto configure = menu->addAction(QIcon::fromTheme(QStringLiteral("configure")), i18n("Configure..."));
|
||||
QObject::connect(configure, &QAction::triggered, configure, [](){
|
||||
|
@ -83,9 +83,9 @@ int main(int argc, char** argv)
|
|||
pairMenu->addAction(i18n("Reject"), dev, &DeviceDbusInterface::rejectPairing);
|
||||
}
|
||||
}
|
||||
|
||||
#if (defined Q_OS_MAC || defined Q_OS_WIN)
|
||||
// Add quit menu
|
||||
#if defined Q_OS_MAC
|
||||
|
||||
menu->addAction(i18n("Quit"), [](){
|
||||
auto message = QDBusMessage::createMethodCall(QStringLiteral("org.kde.kdeconnect.daemon"),
|
||||
QStringLiteral("/MainApplication"),
|
||||
|
@ -98,6 +98,14 @@ int main(int argc, char** argv)
|
|||
QStringLiteral("quit"));
|
||||
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
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue