From 6860c0d60de0ad2bb4374096354fadf3d0261a43 Mon Sep 17 00:00:00 2001 From: Vladimir Golovnev Date: Tue, 24 Oct 2023 13:31:01 +0300 Subject: [PATCH] Allow to set qBittorrent as default program Register qBittorrent as possible default program for .torrent files and magnet links during install. PR #19446. --- dist/windows/installer.nsh | 94 ++++++++---------------------------- dist/windows/uninstaller.nsh | 40 ++------------- src/app/application.cpp | 17 ------- src/base/preferences.cpp | 15 ------ src/base/preferences.h | 5 -- src/base/utils/os.cpp | 88 --------------------------------- src/base/utils/os.h | 7 --- src/gui/optionsdialog.cpp | 20 +++++--- src/gui/optionsdialog.h | 1 + src/gui/optionsdialog.ui | 59 +++++++++++++++++++--- 10 files changed, 90 insertions(+), 256 deletions(-) diff --git a/dist/windows/installer.nsh b/dist/windows/installer.nsh index 030404071..09a8ad758 100644 --- a/dist/windows/installer.nsh +++ b/dist/windows/installer.nsh @@ -32,6 +32,27 @@ Section $(inst_qbt_req) ;"qBittorrent (required)" ; Write the installation path into the registry WriteRegStr HKLM "Software\qBittorrent" "InstallLocation" "$INSTDIR" + ; Register qBittorrent as possible default program for .torrent files and magnet links + WriteRegStr HKLM "Software\qBittorrent\Capabilities" "ApplicationDescription" "A BitTorrent client in Qt" + WriteRegStr HKLM "Software\qBittorrent\Capabilities" "ApplicationName" "qBittorrent" + WriteRegStr HKLM "Software\qBittorrent\Capabilities\FileAssociations" ".torrent" "qBittorrent.File.Torrent" + WriteRegStr HKLM "Software\qBittorrent\Capabilities\UrlAssociations" "magnet" "qBittorrent.Url.Magnet" + WriteRegStr HKLM "Software\RegisteredApplications" "qBittorrent" "Software\qBittorrent\Capabilities" + ; Register qBittorrent ProgIDs + WriteRegStr HKLM "Software\Classes\qBittorrent.File.Torrent" "" "Torrent File" + WriteRegStr HKLM "Software\Classes\qBittorrent.File.Torrent\DefaultIcon" "" '"$INSTDIR\qbittorrent.exe",1' + WriteRegStr HKLM "Software\Classes\qBittorrent.File.Torrent\shell\open\command" "" '"$INSTDIR\qbittorrent.exe" "%1"' + WriteRegStr HKLM "Software\Classes\qBittorrent.Url.Magnet" "" "Magnet URI" + WriteRegStr HKLM "Software\Classes\qBittorrent.Url.Magnet\DefaultIcon" "" '"$INSTDIR\qbittorrent.exe",1' + WriteRegStr HKLM "Software\Classes\qBittorrent.Url.Magnet\shell\open\command" "" '"$INSTDIR\qbittorrent.exe" "%1"' + + WriteRegStr HKLM "Software\Classes\.torrent" "Content Type" "application/x-bittorrent" + WriteRegStr HKLM "Software\Classes\magnet" "" "URL:Magnet URI" + WriteRegStr HKLM "Software\Classes\magnet" "Content Type" "application/x-magnet" + WriteRegStr HKLM "Software\Classes\magnet" "URL Protocol" "" + + System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p 0, p 0)' + ; Write the uninstall keys for Windows WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "DisplayName" "qBittorrent" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "UninstallString" '"$INSTDIR\uninst.exe"' @@ -46,13 +67,6 @@ Section $(inst_qbt_req) ;"qBittorrent (required)" IntFmt $0 "0x%08X" $0 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" "EstimatedSize" "$0" - ; qBittorrent ProgID - WriteRegStr HKLM "Software\Classes\qBittorrent" "" "qBittorrent Torrent File" - WriteRegStr HKLM "Software\Classes\qBittorrent" "FriendlyTypeName" "qBittorrent Torrent File" - WriteRegStr HKLM "Software\Classes\qBittorrent\shell" "" "open" - WriteRegStr HKLM "Software\Classes\qBittorrent\shell\open\command" "" '"$INSTDIR\qbittorrent.exe" "%1"' - WriteRegStr HKLM "Software\Classes\qBittorrent\DefaultIcon" "" '"$INSTDIR\qbittorrent.exe",1' - SectionEnd ; Optional section (can be disabled by the user) @@ -82,72 +96,6 @@ Function inst_startup_user FunctionEnd -Section $(inst_torrent) ;"Open .torrent files with qBittorrent" - - ReadRegStr $0 HKLM "Software\Classes\.torrent" "" - - StrCmp $0 "qBittorrent" clear_errors 0 - ;Check if empty string - StrCmp $0 "" clear_errors 0 - ;Write old value to OpenWithProgIds - WriteRegStr HKLM "Software\Classes\.torrent\OpenWithProgIds" $0 "" - - clear_errors: - ClearErrors - - WriteRegStr HKLM "Software\Classes\.torrent" "" "qBittorrent" - WriteRegStr HKLM "Software\Classes\.torrent" "Content Type" "application/x-bittorrent" - - !insertmacro UAC_AsUser_Call Function inst_torrent_user ${UAC_SYNCREGISTERS}|${UAC_SYNCOUTDIR}|${UAC_SYNCINSTDIR} - - System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p 0, p 0)' - -SectionEnd - -Function inst_torrent_user - - ReadRegStr $0 HKCU "Software\Classes\.torrent" "" - - StrCmp $0 "qBittorrent" clear_errors 0 - ;Check if empty string - StrCmp $0 "" clear_errors 0 - ;Write old value to OpenWithProgIds - WriteRegStr HKCU "Software\Classes\.torrent\OpenWithProgIds" $0 "" - - clear_errors: - ClearErrors - - WriteRegStr HKCU "Software\Classes\.torrent" "" "qBittorrent" - WriteRegStr HKCU "Software\Classes\.torrent" "Content Type" "application/x-bittorrent" - -FunctionEnd - -Section $(inst_magnet) ;"Open magnet links with qBittorrent" - - WriteRegStr HKLM "Software\Classes\magnet" "" "URL:Magnet link" - WriteRegStr HKLM "Software\Classes\magnet" "Content Type" "application/x-magnet" - WriteRegStr HKLM "Software\Classes\magnet" "URL Protocol" "" - WriteRegStr HKLM "Software\Classes\magnet\DefaultIcon" "" '"$INSTDIR\qbittorrent.exe",1' - WriteRegStr HKLM "Software\Classes\magnet\shell" "" "open" - WriteRegStr HKLM "Software\Classes\magnet\shell\open\command" "" '"$INSTDIR\qbittorrent.exe" "%1"' - - !insertmacro UAC_AsUser_Call Function inst_magnet_user ${UAC_SYNCREGISTERS}|${UAC_SYNCOUTDIR}|${UAC_SYNCINSTDIR} - - System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p 0, p 0)' - -SectionEnd - -Function inst_magnet_user - - WriteRegStr HKCU "Software\Classes\magnet" "" "URL:Magnet link" - WriteRegStr HKCU "Software\Classes\magnet" "Content Type" "application/x-magnet" - WriteRegStr HKCU "Software\Classes\magnet" "URL Protocol" "" - WriteRegStr HKCU "Software\Classes\magnet\DefaultIcon" "" '"$INSTDIR\qbittorrent.exe",1' - WriteRegStr HKCU "Software\Classes\magnet\shell" "" "open" - WriteRegStr HKCU "Software\Classes\magnet\shell\open\command" "" '"$INSTDIR\qbittorrent.exe" "%1"' - -FunctionEnd - Section $(inst_firewall) DetailPrint $(inst_firewallinfo) diff --git a/dist/windows/uninstaller.nsh b/dist/windows/uninstaller.nsh index 72a13749d..517604935 100644 --- a/dist/windows/uninstaller.nsh +++ b/dist/windows/uninstaller.nsh @@ -19,48 +19,14 @@ Section "un.$(remove_shortcuts)" ;"un.Remove shortcuts" Delete "$DESKTOP\qBittorrent.lnk" SectionEnd -Section "un.$(remove_associations)" ;"un.Remove file associations" - SectionIn RO - ReadRegStr $0 HKLM "Software\Classes\.torrent" "" - StrCmp $0 "qBittorrent" 0 torrent_end - DetailPrint "$(uninst_tor_warn) $0" - DeleteRegValue HKLM "Software\Classes\.torrent" "" - DeleteRegKey /ifempty HKLM "Software\Classes\.torrent" - torrent_end: - - ReadRegStr $0 HKLM "Software\Classes\magnet\shell\open\command" "" - StrCmp $0 '"$INSTDIR\qbittorrent.exe" "%1"' 0 magnet_end - DetailPrint "$(uninst_mag_warn) $0" - DeleteRegKey HKLM "Software\Classes\magnet" - magnet_end: - - !insertmacro UAC_AsUser_Call Function un.remove_associations_user ${UAC_SYNCREGISTERS}|${UAC_SYNCOUTDIR}|${UAC_SYNCINSTDIR} - - System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p 0, p 0)' -SectionEnd - -Function un.remove_associations_user - ReadRegStr $0 HKCU "Software\Classes\.torrent" "" - StrCmp $0 "qBittorrent" 0 torrent_end - DetailPrint "$(uninst_tor_warn) $0" - DeleteRegValue HKCU "Software\Classes\.torrent" "" - DeleteRegKey /ifempty HKCU "Software\Classes\.torrent" - torrent_end: - - ReadRegStr $0 HKCU "Software\Classes\magnet\shell\open\command" "" - StrCmp $0 '"$INSTDIR\qbittorrent.exe" "%1"' 0 magnet_end - DetailPrint "$(uninst_mag_warn) $0" - DeleteRegKey HKCU "Software\Classes\magnet" - magnet_end: -FunctionEnd - Section "un.$(remove_registry)" ;"un.Remove registry keys" SectionIn RO ; Remove registry keys DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\qBittorrent" DeleteRegKey HKLM "Software\qBittorrent" - DeleteRegKey HKLM "Software\Classes\qBittorrent" - + ; Remove ProgIDs + DeleteRegKey HKLM "Software\Classes\qBittorrent.File.Torrent" + DeleteRegKey HKLM "Software\Classes\qBittorrent.Url.Magnet" System::Call 'Shell32::SHChangeNotify(i ${SHCNE_ASSOCCHANGED}, i ${SHCNF_IDLIST}, p 0, p 0)' SectionEnd diff --git a/src/app/application.cpp b/src/app/application.cpp index 5e59826f0..d8b8a5ac4 100644 --- a/src/app/application.cpp +++ b/src/app/application.cpp @@ -885,23 +885,6 @@ int Application::exec() #endif m_window = new MainWindow(this, windowState); delete m_startupProgressDialog; -#ifdef Q_OS_WIN - auto *pref = Preferences::instance(); - if (!pref->neverCheckFileAssoc() && (!Utils::OS::isTorrentFileAssocSet() || !Utils::OS::isMagnetLinkAssocSet())) - { - if (QMessageBox::question(m_window, tr("Torrent file association") - , tr("qBittorrent is not the default application for opening torrent files or Magnet links.\nDo you want to make qBittorrent the default application for these?") - , QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) - { - Utils::OS::setTorrentFileAssoc(true); - Utils::OS::setMagnetLinkAssoc(true); - } - else - { - pref->setNeverCheckFileAssoc(); - } - } -#endif // Q_OS_WIN #endif // DISABLE_GUI #ifndef DISABLE_WEBUI diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 2130546af..31598b5be 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -1293,21 +1293,6 @@ void Preferences::setRecursiveDownloadEnabled(const bool enable) setValue(u"Preferences/Advanced/DisableRecursiveDownload"_s, !enable); } -#ifdef Q_OS_WIN -bool Preferences::neverCheckFileAssoc() const -{ - return value(u"Preferences/Win32/NeverCheckFileAssocation"_s, false); -} - -void Preferences::setNeverCheckFileAssoc(const bool check) -{ - if (check == neverCheckFileAssoc()) - return; - - setValue(u"Preferences/Win32/NeverCheckFileAssocation"_s, check); -} -#endif // Q_OS_WIN - int Preferences::getTrackerPort() const { return value(u"Preferences/Advanced/trackerPort"_s, 9000); diff --git a/src/base/preferences.h b/src/base/preferences.h index 58a13f4a6..3c2cab599 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -287,11 +287,6 @@ public: #endif bool isRecursiveDownloadEnabled() const; void setRecursiveDownloadEnabled(bool enable); -#ifdef Q_OS_WIN - bool neverCheckFileAssoc() const; - void setNeverCheckFileAssoc(bool check = true); -#endif - int getTrackerPort() const; void setTrackerPort(int port); bool isTrackerPortForwardingEnabled() const; diff --git a/src/base/utils/os.cpp b/src/base/utils/os.cpp index 8ee374e3d..b1d2c22a1 100644 --- a/src/base/utils/os.cpp +++ b/src/base/utils/os.cpp @@ -34,18 +34,8 @@ #include #endif // Q_OS_MACOS -#ifdef Q_OS_WIN -#include -#endif // Q_OS_WIN - #include -#ifdef Q_OS_WIN -#include -#include -#include -#endif // Q_OS_WIN - #include "base/global.h" #include "base/path.h" @@ -114,81 +104,3 @@ void Utils::OS::setMagnetLinkAssoc() ::LSSetDefaultHandlerForURLScheme(magnetUrlScheme, myBundleId); } #endif // Q_OS_MACOS - -#ifdef Q_OS_WIN -bool Utils::OS::isTorrentFileAssocSet() -{ - const QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat); - return settings.value(u".torrent/Default"_s).toString() == u"qBittorrent"; -} - -void Utils::OS::setTorrentFileAssoc(const bool set) -{ - if (set == isTorrentFileAssocSet()) - return; - - QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat); - - if (set) - { - const QString oldProgId = settings.value(u".torrent/Default"_s).toString(); - if (!oldProgId.isEmpty() && (oldProgId != u"qBittorrent")) - settings.setValue((u".torrent/OpenWithProgids/" + oldProgId), QString()); - - settings.setValue(u".torrent/Default"_s, u"qBittorrent"_s); - settings.setValue(u".torrent/Content Type"_s, u"application/x-bittorrent"_s); - } - else - { - settings.setValue(u".torrent/Default"_s, QString()); - } - - ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr); -} - -bool Utils::OS::isMagnetLinkAssocSet() -{ - const QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat); - const QString shellCommand = settings.value(u"magnet/shell/open/command/Default"_s).toString(); - - const QRegularExpressionMatch exeRegMatch = QRegularExpression(u"\"([^\"]+)\".*"_s).match(shellCommand); - if (!exeRegMatch.hasMatch()) - return false; - - const Path assocExe {exeRegMatch.captured(1)}; - if (assocExe != Path(qApp->applicationFilePath())) - return false; - - return true; -} - -void Utils::OS::setMagnetLinkAssoc(const bool set) -{ - if (set == isMagnetLinkAssocSet()) - return; - - QSettings settings(u"HKEY_CURRENT_USER\\Software\\Classes"_s, QSettings::NativeFormat); - - if (set) - { - const QString applicationFilePath = Path(qApp->applicationFilePath()).toString(); - const QString commandStr = u'"' + applicationFilePath + u"\" \"%1\""; - const QString iconStr = u'"' + applicationFilePath + u"\",1"; - - settings.setValue(u"magnet/Default"_s, u"URL:Magnet link"_s); - settings.setValue(u"magnet/Content Type"_s, u"application/x-magnet"_s); - settings.setValue(u"magnet/DefaultIcon/Default"_s, iconStr); - settings.setValue(u"magnet/shell/Default"_s, u"open"_s); - settings.setValue(u"magnet/shell/open/command/Default"_s, commandStr); - settings.setValue(u"magnet/URL Protocol"_s, QString()); - } - else - { - // only wipe values that are specific to qbt - settings.setValue(u"magnet/DefaultIcon/Default"_s, QString()); - settings.setValue(u"magnet/shell/open/command/Default"_s, QString()); - } - - ::SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr); -} -#endif // Q_OS_WIN diff --git a/src/base/utils/os.h b/src/base/utils/os.h index 85389277a..43b632365 100644 --- a/src/base/utils/os.h +++ b/src/base/utils/os.h @@ -40,11 +40,4 @@ namespace Utils::OS bool isMagnetLinkAssocSet(); void setMagnetLinkAssoc(); #endif // Q_OS_MACOS - -#ifdef Q_OS_WIN - bool isTorrentFileAssocSet(); - void setTorrentFileAssoc(bool set); - bool isMagnetLinkAssocSet(); - void setMagnetLinkAssoc(bool set); -#endif // Q_OS_WIN } diff --git a/src/gui/optionsdialog.cpp b/src/gui/optionsdialog.cpp index 62ebe959a..a4a935085 100644 --- a/src/gui/optionsdialog.cpp +++ b/src/gui/optionsdialog.cpp @@ -1,5 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2023 Vladimir Golovnev * Copyright (C) 2006 Christophe Dumez * * This program is free software; you can redistribute it and/or @@ -55,6 +56,7 @@ #include "base/utils/io.h" #include "base/utils/misc.h" #include "base/utils/net.h" +#include "base/utils/os.h" #include "base/utils/password.h" #include "base/utils/random.h" #include "addnewtorrentdialog.h" @@ -287,8 +289,6 @@ void OptionsDialog::loadBehaviorTabOptions() #ifdef Q_OS_WIN m_ui->checkStartup->setChecked(pref->WinStartup()); - m_ui->checkAssociateTorrents->setChecked(Utils::OS::isTorrentFileAssocSet()); - m_ui->checkAssociateMagnetLinks->setChecked(Utils::OS::isMagnetLinkAssocSet()); #endif #ifdef Q_OS_MACOS @@ -369,12 +369,23 @@ void OptionsDialog::loadBehaviorTabOptions() connect(m_ui->checkPreventFromSuspendWhenDownloading, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->checkPreventFromSuspendWhenSeeding, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); -#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) +#if defined(Q_OS_MACOS) connect(m_ui->checkAssociateTorrents, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); connect(m_ui->checkAssociateMagnetLinks, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); +#endif + +#if defined(Q_OS_WIN) || defined(Q_OS_MACOS) connect(m_ui->checkProgramUpdates, &QAbstractButton::toggled, this, &ThisType::enableApplyButton); #endif +#ifdef Q_OS_WIN + m_ui->assocPanel->hide(); +#endif + +#ifdef Q_OS_MAC + m_ui->defaultProgramPanel->hide(); +#endif + #if (defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)) && !defined(QBT_USES_DBUS) m_ui->checkPreventFromSuspendWhenDownloading->setDisabled(true); m_ui->checkPreventFromSuspendWhenSeeding->setDisabled(true); @@ -435,9 +446,6 @@ void OptionsDialog::saveBehaviorTabOptions() const #ifdef Q_OS_WIN pref->setWinStartup(WinStartup()); - - Utils::OS::setTorrentFileAssoc(m_ui->checkAssociateTorrents->isChecked()); - Utils::OS::setMagnetLinkAssoc(m_ui->checkAssociateMagnetLinks->isChecked()); #endif #ifndef Q_OS_MACOS diff --git a/src/gui/optionsdialog.h b/src/gui/optionsdialog.h index 6f8c83166..e4d8d14b7 100644 --- a/src/gui/optionsdialog.h +++ b/src/gui/optionsdialog.h @@ -1,5 +1,6 @@ /* * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2023 Vladimir Golovnev * Copyright (C) 2006 Christophe Dumez * * This program is free software; you can redistribute it and/or diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui index 089cbb849..e278a3da4 100644 --- a/src/gui/optionsdialog.ui +++ b/src/gui/optionsdialog.ui @@ -569,17 +569,60 @@ - - - Use qBittorrent for .torrent files - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Use qBittorrent for .torrent files + + + + + + + Use qBittorrent for magnet links + + + + - - - Use qBittorrent for magnet links - + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + <html><head/><body><p>To set qBittorrent as default program for .torrent files and/or Magnet links<br/>you can use <span style=" font-weight:600;">Default Programs</span> dialog from <span style=" font-weight:600;">Control Panel</span>.</p></body></html> + + + +