Skip to content

Commit 9af5ac7

Browse files
committed
fix(installer): enable ANSI color support on Windows, disable if unsupported
Older Windows consoles (cmd.exe) don't process ANSI escape codes by default, showing raw escape sequences like ←[36m instead of colors. Try to enable virtual terminal processing on both stdout and stderr via SetConsoleMode. If that fails (legacy console, redirected output), disable owo_colors globally so output is plain text.
1 parent d735b86 commit 9af5ac7

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

crates/vite_installer/src/main.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,52 @@ fn init_dll_security() {
3838
#[cfg(not(windows))]
3939
fn init_dll_security() {}
4040

41+
/// Enable ANSI color support on Windows.
42+
///
43+
/// Older Windows consoles (cmd.exe) don't process ANSI escape codes by default.
44+
/// We try to enable virtual terminal processing; if that fails (e.g. redirected
45+
/// output, legacy console), we disable colors globally via owo_colors.
46+
#[cfg(windows)]
47+
fn init_colors() {
48+
unsafe extern "system" {
49+
fn GetStdHandle(nStdHandle: u32) -> isize;
50+
fn GetConsoleMode(hConsoleHandle: isize, lpMode: *mut u32) -> i32;
51+
fn SetConsoleMode(hConsoleHandle: isize, dwMode: u32) -> i32;
52+
}
53+
const STD_OUTPUT_HANDLE: u32 = 0xFFFF_FFF5; // -11i32 as u32
54+
const STD_ERROR_HANDLE: u32 = 0xFFFF_FFF4; // -12i32 as u32
55+
const ENABLE_VIRTUAL_TERMINAL_PROCESSING: u32 = 0x0004;
56+
57+
let enable_vt = |std_handle: u32| -> bool {
58+
unsafe {
59+
let handle = GetStdHandle(std_handle);
60+
if handle == -1_isize {
61+
return false;
62+
}
63+
let mut mode: u32 = 0;
64+
if GetConsoleMode(handle, &mut mode) != 0 {
65+
SetConsoleMode(handle, mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING) != 0
66+
} else {
67+
false
68+
}
69+
}
70+
};
71+
72+
// Enable on both stdout (interactive menu) and stderr (info/warn/error)
73+
let stdout_ok = enable_vt(STD_OUTPUT_HANDLE);
74+
let stderr_ok = enable_vt(STD_ERROR_HANDLE);
75+
76+
if !stdout_ok && !stderr_ok {
77+
owo_colors::set_override(false);
78+
}
79+
}
80+
81+
#[cfg(not(windows))]
82+
fn init_colors() {}
83+
4184
fn main() {
4285
init_dll_security();
86+
init_colors();
4387

4488
let opts = cli::parse();
4589

0 commit comments

Comments
 (0)