Can't write to console with WinAPI

Hi there! My code is:

#![no_main]
#![no_std]

#![windows_subsystem = "console"]
#[cfg(windows)] extern crate winapi;

use core::mem::MaybeUninit;
use core::panic::PanicInfo;
use libc::puts;
use core::ptr::null_mut;
use winapi::um::winbase::WinExec;
use winapi::um::processenv::GetStdHandle;
use winapi::um::consoleapi::WriteConsoleW;

#[panic_handler]
#[no_mangle]
pub extern fn panic( _info: &PanicInfo ) -> ! { loop {} }

#[no_mangle]
pub unsafe extern "system" fn mainCRTStartup() -> isize {
    let file = "pen.exe";
    let file = &file as *const _ as *const _;
    let result = WinExec(file, 0);
    let smth = "smth" as *const _ as *const _;
    let console_handle = GetStdHandle(11);
    WriteConsoleW(console_handle, smth, 999999, null_mut(), null_mut());
    return 0;
}

And it does nothing. What did I do wrong?

  1. When calling WinExec, the c-string must be null-terminated.
  2. STD_OUTPUT_HANDLE's value is -11, not 11.
  3. You are writing a c-string with a wide-string function. (WriteConsoleW)
1 Like

Unless you really need WriteConsoleW I would recommend to use printf
If you want to use W function you need to convert UTF-8 to WTF-16 using MultiByteToWideChar

See for example how I set unicode string to clipboard https://github.com/DoumanAsh/clipboard-win/blob/master/src/raw.rs#L378

P.s. C compatible literals can be made using simple macro like (works with string literals only):

macro_rules! c_lit {
    ($e:expr) => {
        core::concat!($e, "\0")
    };
    ($($e:tt)+) => {
        core::concat!($($e)+, "\0")
    };
}

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.