From aeaf001df79d22c4a616708bdc9fc34438eddd2f Mon Sep 17 00:00:00 2001 From: Damien Elmes Date: Sat, 19 Jul 2025 00:04:48 +0700 Subject: [PATCH] Hack back in a fix for lack of ANSI codes on Windows 10 There must be a better way to do this, but someone more familiar with Win32 internals than I will need to discover it. https://forums.ankiweb.net/t/anki-25-08-beta/63645/61 --- Cargo.toml | 2 +- qt/launcher/src/platform/windows.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index db5753893..2ff29cd1a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -141,7 +141,7 @@ walkdir = "2.5.0" which = "8.0.0" widestring = "1.1.0" winapi = { version = "0.3", features = ["wincon", "winreg"] } -windows = { version = "0.61.3", features = ["Media_SpeechSynthesis", "Media_Core", "Foundation_Collections", "Storage_Streams", "Win32_System_Console", "Win32_System_Registry", "Win32_Foundation", "Win32_UI_Shell"] } +windows = { version = "0.61.3", features = ["Media_SpeechSynthesis", "Media_Core", "Foundation_Collections", "Storage_Streams", "Win32_System_Console", "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_Foundation", "Win32_UI_Shell", "Wdk_System_SystemServices"] } wiremock = "0.6.3" xz2 = "0.1.7" zip = { version = "4.1.0", default-features = false, features = ["deflate", "time"] } diff --git a/qt/launcher/src/platform/windows.rs b/qt/launcher/src/platform/windows.rs index 3c060a9de..ebdff6261 100644 --- a/qt/launcher/src/platform/windows.rs +++ b/qt/launcher/src/platform/windows.rs @@ -8,6 +8,7 @@ use anyhow::Context; use anyhow::Result; use widestring::u16cstr; use windows::core::PCWSTR; +use windows::Wdk::System::SystemServices::RtlGetVersion; use windows::Win32::System::Console::AttachConsole; use windows::Win32::System::Console::GetConsoleWindow; use windows::Win32::System::Console::ATTACH_PARENT_PROCESS; @@ -18,8 +19,25 @@ use windows::Win32::System::Registry::HKEY; use windows::Win32::System::Registry::HKEY_CURRENT_USER; use windows::Win32::System::Registry::KEY_READ; use windows::Win32::System::Registry::REG_SZ; +use windows::Win32::System::SystemInformation::OSVERSIONINFOW; use windows::Win32::UI::Shell::SetCurrentProcessExplicitAppUserModelID; +/// Returns true if running on Windows 10 (not Windows 11) +fn is_windows_10() -> bool { + unsafe { + let mut info = OSVERSIONINFOW { + dwOSVersionInfoSize: std::mem::size_of::() as u32, + ..Default::default() + }; + if RtlGetVersion(&mut info).is_ok() { + // Windows 10 has build numbers < 22000, Windows 11 >= 22000 + info.dwBuildNumber < 22000 && info.dwMajorVersion == 10 + } else { + false + } + } +} + pub fn ensure_terminal_shown() -> Result<()> { unsafe { if !GetConsoleWindow().is_invalid() { @@ -29,6 +47,14 @@ pub fn ensure_terminal_shown() -> Result<()> { } if std::env::var("ANKI_IMPLICIT_CONSOLE").is_ok() && attach_to_parent_console() { + // This black magic triggers Windows to switch to the new + // ANSI-supporting console host, which is usually only available + // when the app is built with the console subsystem. + // Only needed on Windows 10, not Windows 11. + if is_windows_10() { + let _ = Command::new("cmd").args(["/C", ""]).status(); + } + // Successfully attached to parent console reconnect_stdio_to_console(); return Ok(());