From b2a556bbada9cac25969346b408aef22ed10a5f6 Mon Sep 17 00:00:00 2001 From: defnax <9952056+defnax@users.noreply.github.com> Date: Tue, 1 Sep 2026 23:15:06 +0200 Subject: [PATCH] Windows multi-client autostart fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Changes: - Each RetroShare executable path now gets its own registry value: RetroShare-. - Multiple installations can independently enable or disable autostart. - Existing legacy RetroShare entries remain recognized. - Legacy entries are migrated/removed only when they belong to the current executable. - Another installation’s autostart entry is never modified. - Minimized startup (-m) remains supported. --- .../src/gui/settings/rsharesettings.cpp | 71 ++++++++++++++++--- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/retroshare-gui/src/gui/settings/rsharesettings.cpp b/retroshare-gui/src/gui/settings/rsharesettings.cpp index d40f6db81..9bddef223 100644 --- a/retroshare-gui/src/gui/settings/rsharesettings.cpp +++ b/retroshare-gui/src/gui/settings/rsharesettings.cpp @@ -20,6 +20,7 @@ *******************************************************************************/ #include +#include #include #include #include @@ -69,7 +70,45 @@ #if defined(Q_OS_WIN) #define STARTUP_REG_KEY "Software\\Microsoft\\Windows\\CurrentVersion\\Run" -#define RETROSHARE_REG_KEY "RetroShare" +#define RETROSHARE_REG_KEY "RetroShare" + +namespace +{ +QString startupExecutablePath() +{ + return QDir::toNativeSeparators( + QDir::cleanPath(QCoreApplication::applicationFilePath())); +} + +QString startupRegistryValueName() +{ + /* Windows paths are case-insensitive. Hashing the normalized executable path + * gives every installation its own Run value while keeping the name stable. */ + const QByteArray path = startupExecutablePath().toCaseFolded().toUtf8(); + const QByteArray pathHash = + QCryptographicHash::hash(path, QCryptographicHash::Sha256).toHex().left(16); + return QStringLiteral(RETROSHARE_REG_KEY "-") + QString::fromLatin1(pathHash); +} + +QString startupCommand(bool minimized) +{ + QString command = QStringLiteral("\"") + startupExecutablePath() + QStringLiteral("\""); + if(minimized) command += QStringLiteral(" -m"); + return command; +} + +bool startupValueBelongsToThisExecutable(const QString& value) +{ + const QString command = value.trimmed(); + const QString executable = startupExecutablePath(); + const QString quotedExecutable = QStringLiteral("\"") + executable + QStringLiteral("\""); + + return command.compare(executable, Qt::CaseInsensitive) == 0 + || command.compare(executable + QStringLiteral(" -m"), Qt::CaseInsensitive) == 0 + || command.compare(quotedExecutable, Qt::CaseInsensitive) == 0 + || command.compare(quotedExecutable + QStringLiteral(" -m"), Qt::CaseInsensitive) == 0; +} +} #endif /* Default bandwidth graph settings */ @@ -775,7 +814,17 @@ RshareSettings::runRetroshareOnBoot(bool &minimized) minimized = false; #if defined(Q_OS_WIN) - QString value = win32_registry_get_key_value(STARTUP_REG_KEY, RETROSHARE_REG_KEY); + QString value = win32_registry_get_key_value( + STARTUP_REG_KEY, startupRegistryValueName()); + + /* Accept the old shared value only when it points at this executable. It is + * migrated to the per-installation value the next time the setting is saved. */ + if(value.isEmpty()) + { + const QString legacyValue = win32_registry_get_key_value( + STARTUP_REG_KEY, RETROSHARE_REG_KEY); + if(startupValueBelongsToThisExecutable(legacyValue)) value = legacyValue; + } if (!value.isEmpty()) { /* Simple check for "-m" */ @@ -795,16 +844,18 @@ RshareSettings::setRunRetroshareOnBoot(bool run, bool minimized) { #if defined(Q_OS_WIN) if (run) { - QString value = "\"" + QDir::toNativeSeparators(QCoreApplication::applicationFilePath()) + "\""; - - if (minimized) { - value += " -m"; - } - - win32_registry_set_key_value(STARTUP_REG_KEY, RETROSHARE_REG_KEY, value); + win32_registry_set_key_value( + STARTUP_REG_KEY, startupRegistryValueName(), + startupCommand(minimized)); } else { - win32_registry_remove_key(STARTUP_REG_KEY, RETROSHARE_REG_KEY); + win32_registry_remove_key(STARTUP_REG_KEY, startupRegistryValueName()); } + + /* Do not disturb another installation which still owns the legacy value. */ + const QString legacyValue = win32_registry_get_key_value( + STARTUP_REG_KEY, RETROSHARE_REG_KEY); + if(startupValueBelongsToThisExecutable(legacyValue)) + win32_registry_remove_key(STARTUP_REG_KEY, RETROSHARE_REG_KEY); #else /* Platforms othe rthan windows aren't supported yet */ Q_UNUSED(run);