简体   繁体   中英

Why do ANSI escape codes sometimes work in CMD

ANSI escape codes do not work by default in cmd.

But however some application do some kind of initialization after which they seem to seem to work during that session.

How do they do this initialization? Here is an example -

I built a simple rust application that uses ANSI codes for colorful output.

显示使用 ANSI 转义码的货物的图像。

However if I first build the project, then close that session and then again start cmd going to the directory in which my compiled project is and then run the executable (this time without using cargo at all in this session)-

ANSI 无货转义码

It seems like applications like cargo (and other applications also) do some kind of initialization step in the cmd after which the terminal seems to recognize ANSI codes.

And also in Python Calling os.system('') before using ANSIescape codes does the job -

ANSI 转义码在 os.system('') 之后起作用

It seems like os.system('') is a bug, and you shoudn't rely on bugs to make your code work. Is there a better way to initialize ANSI escape codes in cmd?

What you're searching for isENABLE_VIRTUAL_TERMINAL_PROCESSING . The reason it sometimes "stops working", is because some applications disable it before exiting. If it was already enabled, then this is when stuff breaks.

However, you can easily enable it (again) by calling SetConsoleMode() using the winapi crate . You can also use the winapi-util crate which makes it a bit easier.

#[cfg(windows)]
pub fn enable_virtual_terminal_processing() {
    use winapi_util::console::Console;

    if let Ok(mut term) = Console::stdout() {
        let _ = term.set_virtual_terminal_processing(true);
    }
    if let Ok(mut term) = Console::stderr() {
        let _ = term.set_virtual_terminal_processing(true);
    }
}
[target.'cfg(windows)'.dependencies]
winapi-util = "0.1"

To be safe you could call enable_virtual_terminal_processing() initially in main() . However, I definitely recommend calling it after executing astd::process::Command , eg:

let output = Command::new("...")
    .args(&["..."])
    .output()
    .expect("failed to execute process");

#[cfg(windows)]
enable_virtual_terminal_processing();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM