How to make a program that does not display the console window?

Adding to Roman Quick's answer if you're using the MSVC toolchain you'll want to pass MSVC linker args instead.

cargo rustc --release -- -Clink-args="/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup"

Rust 1.18 introduced a Windows Subsystem attribute. Turn off the console with:

#![windows_subsystem = "windows"]

When the Rust binaries are linked with the GCC toolchain, to start a program without spawning a command line window we need to pass the -mwindows option to the linker.

Cargo has a cargo rustc mode which can be used to pass extra flags to rustc. Before that was introduced, there was no known way to pass an option to the compiler with Cargo.

When we can not affect the compilation or linking to the desired effect, one workaround is to hide the window after it has been created:

fn hide_console_window() {
    use std::ptr;
    use winapi::um::wincon::GetConsoleWindow;
    use winapi::um::winuser::{ShowWindow, SW_HIDE};

    let window = unsafe {GetConsoleWindow()};
    // https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
    if window != ptr::null_mut() {
        unsafe {
            ShowWindow(window, SW_HIDE);
        }
    }
}

We'll need the following in Cargo.toml to compile the example:

[dependencies]
winapi = {version = "0.3", features = ["wincon", "winuser"]}

When we are running the program from an existing console or IDE:

fn hide_console_window() {
    unsafe { winapi::um::wincon::FreeConsole() };
}

This second method doesn't work if we're starting the application from a batch file, for the batch still owns the console and keeps its from disappearing.


Soon, https://github.com/rust-lang/rust/pull/37501 will land, which is an implementation of RFC 1665 and the correct answer will be

#![windows_subsystem = "windows"]

in your crate root.