if you mean the message should be "printed" to the console window , then you can use the "Console" API. (well, my snippet above pops a message box, which I assume is not CI friendly anyway)
also, don't forget to change the windows_subsystem
attribute to "console". (although technically for a "windows" subsystem program, you can use AttachConsole
to output to the console window of its parent process, it behaves slight differently)
# Cargo.toml
[dependencies]
windows-sys = { version = "0.52.0", features = [
"Win32_Foundation",
"Win32_System_Threading", // for `ExitProcess`
"Win32_System_Console", // for `WriteConsoleA` etc
] }
# ...
// main.rs
#![no_main]
#![no_std]
#![windows_subsystem = "console"]
use core::ffi::c_void;
use core::panic::PanicInfo;
use windows_sys::Win32::System::Console::GetStdHandle;
use windows_sys::Win32::System::Console::WriteConsoleA;
use windows_sys::Win32::System::Console::STD_OUTPUT_HANDLE;
use windows_sys::Win32::System::Threading::ExitProcess;
// used when `windows_subsystem = "windows"`
//use windows_sys::Win32::System::Console::AttachConsole;
//use windows_sys::Win32::System::Console::ATTACH_PARENT_PROCESS;
#[panic_handler]
fn panic(_: &PanicInfo<'_>) -> ! {
unsafe {
ExitProcess(1);
}
}
#[no_mangle]
fn mainCRTStartup() -> ! {
let message = "hello world\n";
unsafe {
// need this when `windows_subsystem = "windows"`
// AttachConsole(ATTACH_PARENT_PROCESS);
// get a handle to the console output buffer
let console = GetStdHandle(STD_OUTPUT_HANDLE);
// write the message to the console buffer
// alternatively, `WriteFile` can be used in this case too, need additional feature flags for `windows-sys` crate
WriteConsoleA(
console,
message.as_ptr().cast::<c_void>(),
message.len() as u32,
core::ptr::null_mut(),
core::ptr::null(),
);
ExitProcess(0)
}
}
PS:
to be honest, it might be fun, but in practice I see very little benefit of perusing such extreme no_std
on Windows (no_main
is fine, but I doubt you would get significant size reduction compared to "normal" rust programs), because you end up using only the native APIs (i.e. unsafe
all over the place) besides core
, it's roughly "C program, but disguised in rust syntax).
the native Win32 (and NT) APIs are very complicated, for anyone who needs to use them a lot, I would recommend the winsafe
crate (whether you are doing min_size
or not):