Reputation: 1352
I'm trying to develop a program that uses the sdl2 library. It works perfectly so far, but when I run the program I get two windows - the sdl2 window and the console window.
How can I hide or not create the console window? Maybe there is some sort of WinMain
?
Upvotes: 43
Views: 28064
Reputation: 51
After hours of searching, in case if anyone wonders how to detach a process from windows console, there's a console api which can be called via win32console.
The trick is to call freeconsole() method in the child process:
// Start the process from parent with Command::new()
// Send markings. For instance arguments to that process via args() associated function, in this case "hidden"
use win32console::console::WinConsole;
if args[1] == "hidden" {
WinConsole::free_console().unwrap();
}
Upvotes: 0
Reputation: 423
How can I hide or not create the console window?
It may be that you can use a creation flag to indicate no window.
winapi = {version = "0.3.9", features = ["winbase"]}
use winapi::um::winbase::CREATE_NO_WINDOW;
let cmd = "run.bat";
Command::new(cmd).creation_flags(CREATE_NO_WINDOW).spawn().ok();
Upvotes: 1
Reputation: 12547
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://learn.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.
Upvotes: 69
Reputation: 1352
After some time I've found a perfect answer!
Cargo now has very useful subcommand - rustc
.
The full build command is like this:
cargo rustc -- -Clink-args="-Wl,--subsystem,windows"
Now we can build debug builds with regular cargo build
, and when we need to make a final build we can use this command:
cargo rustc --release -- -Clink-args="-Wl,--subsystem,windows"
Upvotes: 9
Reputation: 15529
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.
Upvotes: 16
Reputation: 976
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"
Upvotes: 12