Safe/ergonomic wrapper for `winapi`


The original post

I'm porting my small python script that calls win32api into rust.
Are there any safe/ergonomic wrapper for winapi?

Here's a very little version of my own:

mod winwrap {
    use std::ffi::OsString;
    use std::os::windows::ffi::OsStringExt;
    pub use winapi::shared::minwindef::*;
    pub use winapi::shared::ntdef::*;
    pub use winapi::shared::windef::*;
    use winapi::um::processthreadsapi;
    use winapi::um::psapi;
    use winapi::um::winuser;

    const LEN: usize = 1024;

    fn slice_to_os_string_trancate_nul(text: &[u16]) -> OsString {
        if let Some(new_len) = text.iter().position(|x| *x == 0) {
        } else {

    pub fn GetForegroundWindow() -> HWND {
        unsafe { winuser::GetForegroundWindow() }

    /// returns `OsString`, nul char is truncated.
    pub fn GetWindowTextW(hwnd: HWND) -> OsString {
        let text_len = unsafe { winuser::GetWindowTextLengthW(hwnd) };
        // println!("text_len: {}", text_len);

        let mut text = vec![0u16; (text_len + 1) as usize];
        unsafe {
            winuser::GetWindowTextW(hwnd, text.as_mut_ptr(), text_len + 1);

    /// returns `(thread_id, proc_id)` 
    pub fn GetWindowThreadProcessId(hwnd: HWND) -> (DWORD, DWORD) {
        let mut proc_id: DWORD = 0;
        let thread_id = unsafe { winuser::GetWindowThreadProcessId(hwnd, &mut proc_id) };
        (thread_id, proc_id)

    /// returns process handle.
    pub fn OpenProcess(dwDesiredAccess: DWORD, bInheritHandle: BOOL, dwProcessId: DWORD) -> HANDLE {
        unsafe { processthreadsapi::OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId) }

    /// returns `OsString`, nul char is truncated.
    pub fn GetProcessImageFileNameW(hProcess: HANDLE) -> OsString {
        let mut image_file_name = vec![0u16; LEN];
        let _ = unsafe {
                image_file_name.len() as u32,

Caller site looks like this:

    let hwnd = winwrap::GetForegroundWindow();
    println!("hwnd: {:?}", hwnd);

    let text = winwrap::GetWindowTextW(hwnd);
    println!("text: {:?}", text);

    let (thread_id, proc_id) = winwrap::GetWindowThreadProcessId(hwnd);
    println!("thread_id: {}", thread_id);
    println!("proc_id: {}", proc_id);

    let h_process = winwrap::OpenProcess(
    println!("h_process: {:?}", h_process);

    let image_file_name = winwrap::GetProcessImageFileNameW(h_process);
    println!("image_file_name: {:?}", image_file_name);


hwnd: 0x809aa
text: "MINGW64:/c/workmx3/src/winlog"
thread_id: 9684
proc_id: 9680
h_process: 0x3c
image_file_name: "\\Device\\HarddiskVolume3\\Program Files\\Git\\usr\\bin\\mintty.exe"

Well, I have wrapper for clipboard
And some general stuff for my personal use

1 Like

@DoumanAsh Seems nice.
Your crate is providing OO layer and error checks on top of winapi.

@sekineh Well the goal is to make it as easy as possible to use winapi from Rust.
I made multiple iterations until reached more or less stable API for both of these crates.
I also avoid bloating my winapi crates so they are purely dependent on winapi and io::Error to propagate winapi errors

Just a comment in passing on:

I think inevitably someone will mix up which is thread id vs proc id. Maybe put them in a struct with named fields (or newtype the two id types, if that makes more sense).

I agree that the order is source of confusion. But with custom struct, we can't do this:

let (_, proc_id) = GetWindowThreadProcessId(hwnd);

The doc comment will hover on codes and save us. Not all people are using IDE, though.

You can get close:

struct Ids {
    pid: DWORD,
    tid: DWORD,

let Ids {pid, ..} = GetWindowThreadProcessId(hwnd);

Yeah, it worked: