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 #endif
#include <windows.h> #include <windows.h>
#include <QStyleHints> #include <QStyleHints>
#include "console/WindowsConsole.h"
#endif #endif
#include "console/Console.h" #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) 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()) { if (console::isConsole()) {
isANSIColorConsole = true; isANSIColorConsole = true;
} }
#endif
setOrganizationName(BuildConfig.LAUNCHER_NAME); setOrganizationName(BuildConfig.LAUNCHER_NAME);
setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN); setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN);
@ -1415,16 +1402,6 @@ Application::~Application()
{ {
// Shut down logger by setting the logger function to nothing // Shut down logger by setting the logger function to nothing
qInstallMessageHandler(nullptr); 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) void Application::messageReceived(const QByteArray& message)

View file

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

View file

@ -24,12 +24,16 @@
#endif #endif
#include <windows.h> #include <windows.h>
#include <consoleapi.h>
#include <fcntl.h> #include <fcntl.h>
#include <fileapi.h>
#include <io.h> #include <io.h>
#include <stdio.h> #include <stdio.h>
#include <cstddef> #include <cstddef>
#include <iostream> #include <iostream>
namespace console {
void RedirectHandle(DWORD handle, FILE* stream, const char* mode) void RedirectHandle(DWORD handle, FILE* stream, const char* mode)
{ {
HANDLE stdHandle = GetStdHandle(handle); HANDLE stdHandle = GetStdHandle(handle);
@ -157,3 +161,31 @@ std::error_code EnableAnsiSupport()
return {}; 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 #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); void BindCrtHandlesToStdHandles(bool bindStdIn, bool bindStdOut, bool bindStdErr);
bool AttachWindowsConsole(); bool AttachWindowsConsole();
std::error_code EnableAnsiSupport(); 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> #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> #include <filesystem>
namespace fs = std::filesystem; namespace fs = std::filesystem;
FileLinkApp::FileLinkApp(int& argc, char** argv) : QCoreApplication(argc, argv), socket(new QLocalSocket(this)) 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); setOrganizationName(BuildConfig.LAUNCHER_NAME);
setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN); setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN);
setApplicationName(BuildConfig.LAUNCHER_NAME + "FileLink"); setApplicationName(BuildConfig.LAUNCHER_NAME + "FileLink");
@ -234,13 +221,4 @@ FileLinkApp::~FileLinkApp()
qDebug() << "link program shutting down"; qDebug() << "link program shutting down";
// Shut down logger by setting the logger function to nothing // Shut down logger by setting the logger function to nothing
qInstallMessageHandler(nullptr); 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::LinkPair> m_links_to_make;
QList<FS::LinkResult> m_path_results; 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" #include "FileLink.h"
#if defined Q_OS_WIN32
#include "console/WindowsConsole.h"
#endif
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
#if defined Q_OS_WIN32
// attach the parent console
console::WindowsConsoleGuard _consoleGuard;
#endif
FileLinkApp ldh(argc, argv); FileLinkApp ldh(argc, argv);
switch (ldh.status()) { switch (ldh.status()) {

View file

@ -33,13 +33,23 @@
* limitations under the License. * limitations under the License.
*/ */
#include <iostream>
#include "Application.h" #include "Application.h"
#if defined Q_OS_WIN32
#include "console/WindowsConsole.h"
#endif
int main(int argc, char* argv[]) 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 // initialize Qt
Application app(argc, argv); Application app(argc, argv);
switch (app.status()) { switch (app.status()) {
case Application::StartingUp: case Application::StartingUp:
case Application::Initialized: { case Application::Initialized: {

View file

@ -40,14 +40,6 @@
#include <QProgressDialog> #include <QProgressDialog>
#include <memory> #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> #include <filesystem>
namespace fs = std::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) 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); setOrganizationName(BuildConfig.LAUNCHER_NAME);
setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN); setOrganizationDomain(BuildConfig.LAUNCHER_DOMAIN);
setApplicationName(BuildConfig.LAUNCHER_NAME + "Updater"); setApplicationName(BuildConfig.LAUNCHER_NAME + "Updater");
@ -380,16 +366,6 @@ PrismUpdaterApp::~PrismUpdaterApp()
qDebug() << "updater shutting down"; qDebug() << "updater shutting down";
// Shut down logger by setting the logger function to nothing // Shut down logger by setting the logger function to nothing
qInstallMessageHandler(nullptr); 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) void PrismUpdaterApp::fail(const QString& reason)

View file

@ -21,8 +21,18 @@
*/ */
#include "PrismUpdater.h" #include "PrismUpdater.h"
#if defined Q_OS_WIN32
#include "console/WindowsConsole.h"
#endif
int main(int argc, char* argv[]) 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); PrismUpdaterApp wUpApp(argc, argv);
switch (wUpApp.status()) { switch (wUpApp.status()) {