windows-bindgen generates Rust bindings from Windows metadata (.winmd files).
It powers the windows and windows-sys crates and can generate standalone
bindings for any Windows API.
// build.rs
fn main() {
windows_bindgen::bindgen([
"--out", "src/bindings.rs",
"--flat",
"--filter",
"Windows.Win32.Graphics.Direct2D.ID2D1Factory1",
"Windows.Win32.Graphics.Dxgi.IDXGIFactory2",
]).unwrap();
}// build.rs
fn main() {
windows_bindgen::bindgen(["--etc", "bindings.txt"]).unwrap();
}// bindings.txt
--out src/bindings.rs
--flat
--filter
Windows.Win32.UI.WindowsAndMessaging.CreateWindowExW
Windows.Win32.UI.WindowsAndMessaging.DefWindowProcW
Windows.Win32.UI.WindowsAndMessaging.RegisterClassW
| Option | Description |
|---|---|
--in <path> |
Input .winmd file(s) (default: bundled Windows metadata) |
--out <path> |
Output file path |
--filter <types> |
Which types/methods to include |
--flat |
Emit all types in a single module (no namespace hierarchy) |
--sys |
Generate raw C-style bindings (like windows-sys) |
--minimal |
Emit only explicitly listed methods; others become usize vtable slots |
--deps {core,specific,none} |
Dependency mode for shared types |
--derive <traits> |
Additional derives on generated types |
--rustfmt |
Format output with rustfmt |
--implement <ifaces> |
Generate implementation traits for COM interfaces |
--link |
Link macro source |
--package |
Generate a complete crate with Cargo.toml |
The --filter accepts fully-qualified type names from Windows metadata:
| Form | Effect |
|---|---|
Windows.Win32.Graphics.Direct2D.ID2D1Factory |
Include a type |
Windows.Win32.Graphics.Direct2D.ID2D1Factory::{CreateDrawingStateBlock} |
Include specific methods only (with --minimal) |
Windows.Foundation.TimeSpan |
Include a WinRT value type |
With --minimal, unlisted methods become usize vtable slots — the layout is
preserved but no code is generated for methods you don't call. Dependencies
(parameter/return types) are pulled in automatically.
The user-facing CLI surface is small and orthogonal:
| Axis | Options |
|---|---|
| Input | --in |
| Output path / layout | --out, --flat, --package (+--no-toml), --index |
| Filter | --filter, --implement[…] |
| Code style | --sys (+--extern), --minimal |
| Dependencies | --deps {core,specific,none}, --link |
| Misc | --derive, --rustfmt, --reference, --etc |
Key design decisions:
-
--sysvs--minimalare the same "lean mode" axis but produce different ABI contracts —--minimalpreserves vtable/_Impl/RuntimeType,--sysdoes not. Two flags, one internal enum (Style), is the right shape. -
--deps nonevs--sysare orthogonal.--deps noneis also meaningful with--minimal(for crates that bootstrap themselves). -
--filtermethod-level grammar (?Ns.Type,Ns.Type::Method, etc.) is a deliberate DSL with documented escape hatches — better than an expanding set of top-level flags. -
--packagevs--flatvs default modules are three distinct output topologies driving different writer code paths, modelled as aLayoutenum.