refactor(console): attach console early

also use RAII guard to free it instead of tracking it with a member variable

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
Rachel Powers 2025-12-12 20:11:04 -07:00
parent 35121f26fd
commit ffd50e318a
No known key found for this signature in database
GPG key ID: B4CB507E51F8B89C
10 changed files with 79 additions and 80 deletions

View file

@ -157,7 +157,6 @@
#endif
#include <windows.h>
#include <QStyleHints>
#include "console/WindowsConsole.h"
#endif
#include "console/Console.h"
@ -291,21 +290,9 @@ std::tuple<QDateTime, QString, QString, QString, QString> read_lock_File(const Q
Application::Application(int& argc, char** argv) : QApplication(argc, argv)
{
#if defined Q_OS_WIN32
// attach the parent console if stdout not already captured
if (AttachWindowsConsole()) {
consoleAttached = true;
if (auto err = EnableAnsiSupport(); !err) {
isANSIColorConsole = true;
} else {
std::cout << "Error setting up ansi console" << err.message() << std::endl;
}
}
#else
if (console::isConsole()) {
isANSIColorConsole = true;
}
#endif
setOrganizationName(BuildConfig.LAUNCHER_NAME);
setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN);
@ -1415,16 +1402,6 @@ Application::~Application()
{
// Shut down logger by setting the logger function to nothing
qInstallMessageHandler(nullptr);
#if defined Q_OS_WIN32
// Detach from Windows console
if (consoleAttached) {
fclose(stdout);
fclose(stdin);
fclose(stderr);
FreeConsole();
}
#endif
}
void Application::messageReceived(const QByteArray& message)

View file

@ -274,11 +274,6 @@ class Application : public QApplication {
Qt::ApplicationState m_prevAppState = Qt::ApplicationInactive;
#endif
#if defined Q_OS_WIN32
// used on Windows to attach the standard IO streams
bool consoleAttached = false;
#endif
// FIXME: attach to instances instead.
struct InstanceXtras {
InstanceWindow* window = nullptr;

View file

@ -24,12 +24,16 @@
#endif
#include <windows.h>
#include <consoleapi.h>
#include <fcntl.h>
#include <fileapi.h>
#include <io.h>
#include <stdio.h>
#include <cstddef>
#include <iostream>
namespace console {
void RedirectHandle(DWORD handle, FILE* stream, const char* mode)
{
HANDLE stdHandle = GetStdHandle(handle);
@ -157,3 +161,31 @@ std::error_code EnableAnsiSupport()
return {};
}
void FreeWindowsConsole()
{
fclose(stdout);
fclose(stdin);
fclose(stderr);
FreeConsole();
}
WindowsConsoleGuard::WindowsConsoleGuard() : m_consoleAttached(false)
{
if (console::AttachWindowsConsole()) {
m_consoleAttached = true;
if (auto err = console::EnableAnsiSupport(); err) {
std::cout << "Error setting up ansi console" << err.message() << std::endl;
}
}
}
WindowsConsoleGuard::~WindowsConsoleGuard()
{
// Detach from Windows console
if (m_consoleAttached) {
console::FreeWindowsConsole();
}
}
} // namespace console

View file

@ -21,8 +21,24 @@
#pragma once
#include <system_error>
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <system_error>
namespace console {
void BindCrtHandlesToStdHandles(bool bindStdIn, bool bindStdOut, bool bindStdErr);
bool AttachWindowsConsole();
std::error_code EnableAnsiSupport();
void FreeWindowsConsole();
class WindowsConsoleGuard {
public:
WindowsConsoleGuard();
~WindowsConsoleGuard();
private:
bool m_consoleAttached;
};
} // namespace console

View file

@ -34,24 +34,11 @@
#include <DesktopServices.h>
#if defined Q_OS_WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include "console/WindowsConsole.h"
#endif
#include <filesystem>
namespace fs = std::filesystem;
FileLinkApp::FileLinkApp(int& argc, char** argv) : QCoreApplication(argc, argv), socket(new QLocalSocket(this))
{
#if defined Q_OS_WIN32
// attach the parent console
if (AttachWindowsConsole()) {
consoleAttached = true;
}
#endif
setOrganizationName(BuildConfig.LAUNCHER_NAME);
setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN);
setApplicationName(BuildConfig.LAUNCHER_NAME + "FileLink");
@ -234,13 +221,4 @@ FileLinkApp::~FileLinkApp()
qDebug() << "link program shutting down";
// Shut down logger by setting the logger function to nothing
qInstallMessageHandler(nullptr);
#if defined Q_OS_WIN32
// Detach from Windows console
if (consoleAttached) {
fclose(stdout);
fclose(stdin);
fclose(stderr);
}
#endif
}

View file

@ -64,8 +64,4 @@ class FileLinkApp : public QCoreApplication {
QList<FS::LinkPair> m_links_to_make;
QList<FS::LinkResult> m_path_results;
#if defined Q_OS_WIN32
// used on Windows to attach the standard IO streams
bool consoleAttached = false;
#endif
};

View file

@ -22,8 +22,17 @@
#include "FileLink.h"
#if defined Q_OS_WIN32
#include "console/WindowsConsole.h"
#endif
int main(int argc, char* argv[])
{
#if defined Q_OS_WIN32
// attach the parent console
console::WindowsConsoleGuard _consoleGuard;
#endif
FileLinkApp ldh(argc, argv);
switch (ldh.status()) {

View file

@ -33,13 +33,23 @@
* limitations under the License.
*/
#include <iostream>
#include "Application.h"
#if defined Q_OS_WIN32
#include "console/WindowsConsole.h"
#endif
int main(int argc, char* argv[])
{
#if defined Q_OS_WIN32
// used on Windows to attach the standard IO streams
console::WindowsConsoleGuard _consoleGuard;
#endif
// initialize Qt
Application app(argc, argv);
switch (app.status()) {
case Application::StartingUp:
case Application::Initialized: {

View file

@ -40,14 +40,6 @@
#include <QProgressDialog>
#include <memory>
#if defined Q_OS_WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#include "console/WindowsConsole.h"
#endif
#include <filesystem>
namespace fs = std::filesystem;
@ -84,12 +76,6 @@ void appDebugOutput(QtMsgType type, const QMessageLogContext& context, const QSt
PrismUpdaterApp::PrismUpdaterApp(int& argc, char** argv) : QApplication(argc, argv)
{
#if defined Q_OS_WIN32
// attach the parent console if stdout not already captured
if (AttachWindowsConsole()) {
consoleAttached = true;
}
#endif
setOrganizationName(BuildConfig.LAUNCHER_NAME);
setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN);
setApplicationName(BuildConfig.LAUNCHER_NAME + "Updater");
@ -380,16 +366,6 @@ PrismUpdaterApp::~PrismUpdaterApp()
qDebug() << "updater shutting down";
// Shut down logger by setting the logger function to nothing
qInstallMessageHandler(nullptr);
#if defined Q_OS_WIN32
// Detach from Windows console
if (consoleAttached) {
fclose(stdout);
fclose(stdin);
fclose(stderr);
FreeConsole();
}
#endif
}
void PrismUpdaterApp::fail(const QString& reason)

View file

@ -21,8 +21,18 @@
*/
#include "PrismUpdater.h"
#if defined Q_OS_WIN32
#include "console/WindowsConsole.h"
#endif
int main(int argc, char* argv[])
{
#if defined Q_OS_WIN32
// attach the parent console if stdout not already captured
console::WindowsConsoleGuard _consoleGuard;
#endif
PrismUpdaterApp wUpApp(argc, argv);
switch (wUpApp.status()) {