Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to set qBittorrent as default program #19446

Merged
merged 1 commit into from
Oct 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 21 additions & 73 deletions dist/windows/installer.nsh
Original file line number Diff line number Diff line change
Expand Up @@ -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"'
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
40 changes: 3 additions & 37 deletions dist/windows/uninstaller.nsh
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
17 changes: 0 additions & 17 deletions src/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 0 additions & 15 deletions src/base/preferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<int>(u"Preferences/Advanced/trackerPort"_s, 9000);
Expand Down
5 changes: 0 additions & 5 deletions src/base/preferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,6 @@ class Preferences final : public QObject
#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;
Expand Down
88 changes: 0 additions & 88 deletions src/base/utils/os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,18 +34,8 @@
#include <CoreServices/CoreServices.h>
#endif // Q_OS_MACOS

#ifdef Q_OS_WIN
#include <shlobj.h>
#endif // Q_OS_WIN

#include <QString>

#ifdef Q_OS_WIN
#include <QCoreApplication>
#include <QRegularExpression>
#include <QSettings>
#endif // Q_OS_WIN

#include "base/global.h"
#include "base/path.h"

Expand Down Expand Up @@ -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
7 changes: 0 additions & 7 deletions src/base/utils/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
20 changes: 14 additions & 6 deletions src/gui/optionsdialog.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
* Bittorrent Client using Qt and libtorrent.
* Copyright (C) 2023 Vladimir Golovnev <glassez@yandex.ru>
* Copyright (C) 2006 Christophe Dumez <chris@qbittorrent.org>
*
* This program is free software; you can redistribute it and/or
Expand Down Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down
Loading