diff --git a/src/app/application.cpp b/src/app/application.cpp
index 867bd5a0f..0a3c254b3 100644
--- a/src/app/application.cpp
+++ b/src/app/application.cpp
@@ -332,23 +332,47 @@ void Application::runExternalProgram(const BitTorrent::TorrentHandle *torrent) c
     logger->addMessage(tr("Torrent: %1, running external program, command: %2").arg(torrent->name(), program));
 
 #if defined(Q_OS_WIN)
-    std::unique_ptr<wchar_t[]> programWchar(new wchar_t[program.length() + 1] {});
+    auto programWchar = std::make_unique<wchar_t[]>(program.length() + 1);
     program.toWCharArray(programWchar.get());
 
     // Need to split arguments manually because QProcess::startDetached(QString)
     // will strip off empty parameters.
     // E.g. `python.exe "1" "" "3"` will become `python.exe "1" "3"`
     int argCount = 0;
-    LPWSTR *args = ::CommandLineToArgvW(programWchar.get(), &argCount);
+    std::unique_ptr<LPWSTR[], decltype(&::LocalFree)> args {::CommandLineToArgvW(programWchar.get(), &argCount), ::LocalFree};
 
     QStringList argList;
     for (int i = 1; i < argCount; ++i)
         argList += QString::fromWCharArray(args[i]);
 
-    QProcess::startDetached(QString::fromWCharArray(args[0]), argList);
-
-    ::LocalFree(args);
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
+    QProcess proc;
+    proc.setProgram(QString::fromWCharArray(args[0]));
+    proc.setArguments(argList);
+    proc.setCreateProcessArgumentsModifier([](QProcess::CreateProcessArguments *args)
+    {
+        if (Preferences::instance()->isAutoRunConsoleEnabled()) {
+            args->flags |= CREATE_NEW_CONSOLE;
+            args->flags &= ~(CREATE_NO_WINDOW | DETACHED_PROCESS);
+        }
+        else {
+            args->flags |= CREATE_NO_WINDOW;
+            args->flags &= ~(CREATE_NEW_CONSOLE | DETACHED_PROCESS);
+        }
+        args->inheritHandles = false;
+        args->startupInfo->dwFlags &= ~STARTF_USESTDHANDLES;
+        ::CloseHandle(args->startupInfo->hStdInput);
+        ::CloseHandle(args->startupInfo->hStdOutput);
+        ::CloseHandle(args->startupInfo->hStdError);
+        args->startupInfo->hStdInput = nullptr;
+        args->startupInfo->hStdOutput = nullptr;
+        args->startupInfo->hStdError = nullptr;
+    });
+    proc.startDetached();
 #else
+    QProcess::startDetached(QString::fromWCharArray(args[0]), argList);
+#endif // QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
+#else // Q_OS_WIN
     // Cannot give users shell environment by default, as doing so could
     // enable command injection via torrent name and other arguments
     // (especially when some automated download mechanism has been setup).
diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp
index 2bbb5e33f..683f073fe 100644
--- a/src/base/preferences.cpp
+++ b/src/base/preferences.cpp
@@ -781,7 +781,7 @@ bool Preferences::isUILocked() const
 
 void Preferences::setUILocked(const bool locked)
 {
-    return setValue("Locking/locked", locked);
+    setValue("Locking/locked", locked);
 }
 
 bool Preferences::isAutoRunEnabled() const
@@ -791,7 +791,7 @@ bool Preferences::isAutoRunEnabled() const
 
 void Preferences::setAutoRunEnabled(const bool enabled)
 {
-    return setValue("AutoRun/enabled", enabled);
+    setValue("AutoRun/enabled", enabled);
 }
 
 QString Preferences::getAutoRunProgram() const
@@ -804,6 +804,18 @@ void Preferences::setAutoRunProgram(const QString &program)
     setValue("AutoRun/program", program);
 }
 
+#if defined(Q_OS_WIN) && (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
+bool Preferences::isAutoRunConsoleEnabled() const
+{
+    return value("AutoRun/ConsoleEnabled", false).toBool();
+}
+
+void Preferences::setAutoRunConsoleEnabled(const bool enabled)
+{
+    setValue("AutoRun/ConsoleEnabled", enabled);
+}
+#endif
+
 bool Preferences::shutdownWhenDownloadsComplete() const
 {
     return value("Preferences/Downloads/AutoShutDownOnCompletion", false).toBool();
diff --git a/src/base/preferences.h b/src/base/preferences.h
index d141e1639..19723d70d 100644
--- a/src/base/preferences.h
+++ b/src/base/preferences.h
@@ -238,6 +238,10 @@ public:
     void setAutoRunEnabled(bool enabled);
     QString getAutoRunProgram() const;
     void setAutoRunProgram(const QString &program);
+#if defined(Q_OS_WIN) && (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
+    bool isAutoRunConsoleEnabled() const;
+    void setAutoRunConsoleEnabled(bool enabled);
+#endif
     bool shutdownWhenDownloadsComplete() const;
     void setShutdownWhenDownloadsComplete(bool shutdown);
     bool suspendWhenDownloadsComplete() const;
diff --git a/src/gui/optionsdialog.cpp b/src/gui/optionsdialog.cpp
index 95cb6c604..44c4a9e02 100644
--- a/src/gui/optionsdialog.cpp
+++ b/src/gui/optionsdialog.cpp
@@ -295,6 +295,7 @@ OptionsDialog::OptionsDialog(QWidget *parent)
     connect(m_ui->mailNotifPassword, &QLineEdit::textChanged, this, &ThisType::enableApplyButton);
     connect(m_ui->autoRunBox, &QGroupBox::toggled, this, &ThisType::enableApplyButton);
     connect(m_ui->lineEditAutoRun, &QLineEdit::textChanged, this, &ThisType::enableApplyButton);
+    connect(m_ui->autoRunConsole, &QCheckBox::toggled, this, &ThisType::enableApplyButton);
 
     const QString autoRunStr = QString("%1\n    %2\n    %3\n    %4\n    %5\n    %6\n    %7\n    %8\n    %9\n    %10\n    %11\n%12")
         .arg(tr("Supported parameters (case sensitive):")
@@ -696,6 +697,9 @@ void OptionsDialog::saveOptions()
     pref->setMailNotificationSMTPPassword(m_ui->mailNotifPassword->text());
     pref->setAutoRunEnabled(m_ui->autoRunBox->isChecked());
     pref->setAutoRunProgram(m_ui->lineEditAutoRun->text().trimmed());
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) && defined(Q_OS_WIN)
+    pref->setAutoRunConsoleEnabled(m_ui->autoRunConsole->isChecked());
+#endif
     pref->setActionOnDblClOnTorrentDl(getActionOnDblClOnTorrentDl());
     pref->setActionOnDblClOnTorrentFn(getActionOnDblClOnTorrentFn());
     TorrentFileGuard::setAutoDeleteMode(!m_ui->deleteTorrentBox->isChecked() ? TorrentFileGuard::Never
@@ -970,6 +974,11 @@ void OptionsDialog::loadOptions()
 
     m_ui->autoRunBox->setChecked(pref->isAutoRunEnabled());
     m_ui->lineEditAutoRun->setText(pref->getAutoRunProgram());
+#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)) && defined(Q_OS_WIN)
+    m_ui->autoRunConsole->setChecked(pref->isAutoRunConsoleEnabled());
+#else
+    m_ui->autoRunConsole->hide();
+#endif
     intValue = pref->getActionOnDblClOnTorrentDl();
     if (intValue >= m_ui->actionTorrentDlOnDblClBox->count())
         intValue = 0;
diff --git a/src/gui/optionsdialog.ui b/src/gui/optionsdialog.ui
index 3ede266bf..f0988c327 100644
--- a/src/gui/optionsdialog.ui
+++ b/src/gui/optionsdialog.ui
@@ -1264,6 +1264,13 @@
                <item>
                 <widget class="QLineEdit" name="lineEditAutoRun"/>
                </item>
+               <item>
+                <widget class="QCheckBox" name="autoRunConsole">
+                 <property name="text">
+                  <string>Show console window</string>
+                 </property>
+                </widget>
+               </item>
                <item>
                 <widget class="QLabel" name="labelAutoRunParam">
                  <property name="wordWrap">
