Skip to content

Commit

Permalink
Add crate-specific readme files (#2703)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Nov 15, 2023
1 parent a80df1e commit 3a605cb
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 202 deletions.
87 changes: 21 additions & 66 deletions crates/libs/bindgen/readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Rust for Windows
## Generate Rust bindings for Windows

The [windows](https://crates.io/crates/windows) and [windows-sys](https://crates.io/crates/windows-sys) crates let you call any Windows API past, present, and future using code generated on the fly directly from the [metadata describing the API](https://github.com/microsoft/windows-rs/tree/master/crates/libs/bindgen/default) and right into your Rust package where you can call them as if they were just another Rust module. The Rust language projection follows in the tradition established by [C++/WinRT](https://github.com/microsoft/cppwinrt) of building language projections for Windows using standard languages and compilers, providing a natural and idiomatic way for Rust developers to call Windows APIs.
The [windows-bindgen](https://crates.io/crates/windows-bindgen) crate automatically generates Rust bindings from Windows metadata.

* [Getting started](https://kennykerr.ca/rust-getting-started/)
* [Samples](https://github.com/microsoft/windows-rs/tree/0.52.0/crates/samples) <!-- link to samples for upcoming release -->
Expand All @@ -9,80 +9,35 @@ The [windows](https://crates.io/crates/windows) and [windows-sys](https://crates
Start by adding the following to your Cargo.toml file:

```toml
[dependencies.windows]
[dependencies.windows-targets]
version = "0.52"
features = [
"Data_Xml_Dom",
"Win32_Foundation",
"Win32_Security",
"Win32_System_Threading",
"Win32_UI_WindowsAndMessaging",
]
```

Make use of any Windows APIs as needed:

```rust,no_run
use windows::{
core::*, Data::Xml::Dom::*, Win32::Foundation::*, Win32::System::Threading::*,
Win32::UI::WindowsAndMessaging::*,
};
fn main() -> Result<()> {
let doc = XmlDocument::new()?;
doc.LoadXml(h!("<html>hello world</html>"))?;
let root = doc.DocumentElement()?;
assert!(root.NodeName()? == "html");
assert!(root.InnerText()? == "hello world");

unsafe {
let event = CreateEventW(None, true, false, None)?;
SetEvent(event)?;
WaitForSingleObject(event, 0);
CloseHandle(event)?;
MessageBoxA(None, s!("Ansi"), s!("Caption"), MB_OK);
MessageBoxW(None, w!("Wide"), w!("Caption"), MB_OK);
}
Ok(())
}
```

## windows-sys

The `windows-sys` crate is a zero-overhead fallback for the most demanding situations and primarily where the absolute best compile time is essential. It only includes function declarations (externs), structs, and constants. No convenience helpers, traits, or wrappers are provided.

Start by adding the following to your Cargo.toml file:

```toml
[dependencies.windows-sys]
[dev-dependencies.windows-bindgen]
version = "0.52"
features = [
"Win32_Foundation",
"Win32_Security",
"Win32_System_Threading",
"Win32_UI_WindowsAndMessaging",
]
```

Make use of any Windows APIs as needed:
Generates Rust bindings in a build script or test as needed:

```rust,no_run
use windows_sys::{
core::*, Win32::Foundation::*, Win32::System::Threading::*, Win32::UI::WindowsAndMessaging::*,
};
#[test]
fn bindgen() {
let args = [
"--out",
"src/bindings.rs",
"--config",
"flatten",
"--filter",
"Windows.Win32.System.SystemInformation.GetTickCount",
];
windows_bindgen::bindgen(args).unwrap();
}
mod bindings;
fn main() {
unsafe {
let event = CreateEventW(std::ptr::null(), 1, 0, std::ptr::null());
SetEvent(event);
WaitForSingleObject(event, 0);
CloseHandle(event);
MessageBoxA(0, s!("Ansi"), s!("Caption"), MB_OK);
MessageBoxW(0, w!("Wide"), w!("Caption"), MB_OK);
println!("{}", bindings::GetTickCount());
}
}
```
81 changes: 15 additions & 66 deletions crates/libs/metadata/readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Rust for Windows
## Windows metadata reader

The [windows](https://crates.io/crates/windows) and [windows-sys](https://crates.io/crates/windows-sys) crates let you call any Windows API past, present, and future using code generated on the fly directly from the [metadata describing the API](https://github.com/microsoft/windows-rs/tree/master/crates/libs/bindgen/default) and right into your Rust package where you can call them as if they were just another Rust module. The Rust language projection follows in the tradition established by [C++/WinRT](https://github.com/microsoft/cppwinrt) of building language projections for Windows using standard languages and compilers, providing a natural and idiomatic way for Rust developers to call Windows APIs.
The [windows-metadata](https://crates.io/crates/windows-metadata) crate provides a fast reader for Windows metadata files based on the ECMA-335 file format.

* [Getting started](https://kennykerr.ca/rust-getting-started/)
* [Samples](https://github.com/microsoft/windows-rs/tree/0.52.0/crates/samples) <!-- link to samples for upcoming release -->
Expand All @@ -9,80 +9,29 @@ The [windows](https://crates.io/crates/windows) and [windows-sys](https://crates
Start by adding the following to your Cargo.toml file:

```toml
[dependencies.windows]
[dependencies.windows-metadata]
version = "0.52"
features = [
"Data_Xml_Dom",
"Win32_Foundation",
"Win32_Security",
"Win32_System_Threading",
"Win32_UI_WindowsAndMessaging",
]
```

Make use of any Windows APIs as needed:
Read metadata as needed:

```rust,no_run
use windows::{
core::*, Data::Xml::Dom::*, Win32::Foundation::*, Win32::System::Threading::*,
Win32::UI::WindowsAndMessaging::*,
};
use windows_metadata::*;
fn main() -> Result<()> {
let doc = XmlDocument::new()?;
doc.LoadXml(h!("<html>hello world</html>"))?;
let root = doc.DocumentElement()?;
assert!(root.NodeName()? == "html");
assert!(root.InnerText()? == "hello world");
unsafe {
let event = CreateEventW(None, true, false, None)?;
SetEvent(event)?;
WaitForSingleObject(event, 0);
CloseHandle(event)?;
MessageBoxA(None, s!("Ansi"), s!("Caption"), MB_OK);
MessageBoxW(None, w!("Wide"), w!("Caption"), MB_OK);
}
Ok(())
}
```

## windows-sys

The `windows-sys` crate is a zero-overhead fallback for the most demanding situations and primarily where the absolute best compile time is essential. It only includes function declarations (externs), structs, and constants. No convenience helpers, traits, or wrappers are provided.

Start by adding the following to your Cargo.toml file:

```toml
[dependencies.windows-sys]
version = "0.52"
features = [
"Win32_Foundation",
"Win32_Security",
"Win32_System_Threading",
"Win32_UI_WindowsAndMessaging",
]
```
fn main() {
let bytes = std::fs::read(r#"C:\Windows\System32\WinMetadata\Windows.Foundation.winmd"#)
.expect("File not found");
Make use of any Windows APIs as needed:
let file = File::new(bytes).expect("Invalid metadata");
```rust,no_run
use windows_sys::{
core::*, Win32::Foundation::*, Win32::System::Threading::*, Win32::UI::WindowsAndMessaging::*,
};
let reader = Reader::new(vec![file]);
fn main() {
unsafe {
let event = CreateEventW(std::ptr::null(), 1, 0, std::ptr::null());
SetEvent(event);
WaitForSingleObject(event, 0);
CloseHandle(event);
for def in reader.get_type_def("Windows.Foundation", "IAsyncInfo") {
println!("{}", def.name());
MessageBoxA(0, s!("Ansi"), s!("Caption"), MB_OK);
MessageBoxW(0, w!("Wide"), w!("Caption"), MB_OK);
for method in def.methods() {
println!("{}", method.name());
}
}
}
```
76 changes: 8 additions & 68 deletions crates/libs/targets/readme.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## Rust for Windows
## Import libs for Windows

The [windows](https://crates.io/crates/windows) and [windows-sys](https://crates.io/crates/windows-sys) crates let you call any Windows API past, present, and future using code generated on the fly directly from the [metadata describing the API](https://github.com/microsoft/windows-rs/tree/master/crates/libs/bindgen/default) and right into your Rust package where you can call them as if they were just another Rust module. The Rust language projection follows in the tradition established by [C++/WinRT](https://github.com/microsoft/cppwinrt) of building language projections for Windows using standard languages and compilers, providing a natural and idiomatic way for Rust developers to call Windows APIs.
The [windows-targets](https://crates.io/crates/windows-targets) crate includes import libs, supports semantic versioning, and optional support for raw-dylib.

* [Getting started](https://kennykerr.ca/rust-getting-started/)
* [Samples](https://github.com/microsoft/windows-rs/tree/0.52.0/crates/samples) <!-- link to samples for upcoming release -->
Expand All @@ -9,80 +9,20 @@ The [windows](https://crates.io/crates/windows) and [windows-sys](https://crates
Start by adding the following to your Cargo.toml file:

```toml
[dependencies.windows]
[dependencies.windows-targets]
version = "0.52"
features = [
"Data_Xml_Dom",
"Win32_Foundation",
"Win32_Security",
"Win32_System_Threading",
"Win32_UI_WindowsAndMessaging",
]
```

Make use of any Windows APIs as needed:
Use the `link`` macro to define the external functions you wish to call:

```rust,no_run
use windows::{
core::*, Data::Xml::Dom::*, Win32::Foundation::*, Win32::System::Threading::*,
Win32::UI::WindowsAndMessaging::*,
};
fn main() -> Result<()> {
let doc = XmlDocument::new()?;
doc.LoadXml(h!("<html>hello world</html>"))?;
let root = doc.DocumentElement()?;
assert!(root.NodeName()? == "html");
assert!(root.InnerText()? == "hello world");
unsafe {
let event = CreateEventW(None, true, false, None)?;
SetEvent(event)?;
WaitForSingleObject(event, 0);
CloseHandle(event)?;
MessageBoxA(None, s!("Ansi"), s!("Caption"), MB_OK);
MessageBoxW(None, w!("Wide"), w!("Caption"), MB_OK);
}
Ok(())
}
```

## windows-sys

The `windows-sys` crate is a zero-overhead fallback for the most demanding situations and primarily where the absolute best compile time is essential. It only includes function declarations (externs), structs, and constants. No convenience helpers, traits, or wrappers are provided.

Start by adding the following to your Cargo.toml file:

```toml
[dependencies.windows-sys]
version = "0.52"
features = [
"Win32_Foundation",
"Win32_Security",
"Win32_System_Threading",
"Win32_UI_WindowsAndMessaging",
]
```

Make use of any Windows APIs as needed:

```rust,no_run
use windows_sys::{
core::*, Win32::Foundation::*, Win32::System::Threading::*, Win32::UI::WindowsAndMessaging::*,
};
windows_targets::link!("kernel32.dll" "system" fn SetLastError(code: u32));
windows_targets::link!("kernel32.dll" "system" fn GetLastError() -> u32);
fn main() {
unsafe {
let event = CreateEventW(std::ptr::null(), 1, 0, std::ptr::null());
SetEvent(event);
WaitForSingleObject(event, 0);
CloseHandle(event);
MessageBoxA(0, s!("Ansi"), s!("Caption"), MB_OK);
MessageBoxW(0, w!("Wide"), w!("Caption"), MB_OK);
SetLastError(1234);
assert_eq!(GetLastError(), 1234);
}
}
```
6 changes: 6 additions & 0 deletions crates/tests/readme/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,9 @@ features = [
"Win32_System_Threading",
"Win32_UI_WindowsAndMessaging",
]

[dependencies.windows-targets]
path = "../../libs/targets"

[dependencies.windows-metadata]
path = "../../libs/metadata"
1 change: 0 additions & 1 deletion crates/tests/readme/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#![doc = include_str!("../../../../crates/libs/bindgen/readme.md")]
#![doc = include_str!("../../../../crates/libs/core/readme.md")]
#![doc = include_str!("../../../../crates/libs/metadata/readme.md")]
#![doc = include_str!("../../../../crates/libs/sys/readme.md")]
Expand Down
3 changes: 2 additions & 1 deletion crates/tools/riddle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[package]
name = "riddle"
version = "0.0.1"
version = "0.1.0"
authors = ["Microsoft"]
edition = "2021"
rust-version = "1.56"
license = "MIT OR Apache-2.0"
description = "Windows metadata compiler"
repository = "https://github.com/microsoft/windows-rs"
readme = "readme.md"

[dependencies.windows-bindgen]
path = "../../libs/bindgen"
Expand Down
28 changes: 28 additions & 0 deletions crates/tools/riddle/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
## Generate Rust bindings for Windows

The [riddle](https://crates.io/crates/riddle) tool automatically generates Rust bindings from Windows metadata.

* [Getting started](https://kennykerr.ca/rust-getting-started/)
* [Samples](https://github.com/microsoft/windows-rs/tree/0.52.0/crates/samples) <!-- link to samples for upcoming release -->
* [Releases](https://github.com/microsoft/windows-rs/releases)

Start by installing `riddle`:

```
> cargo install riddle
```

Generates Rust bindings as needed:

```
> riddle
Usage: riddle.exe [options...]
Options:
--in <path> Path to files and directories containing .winmd and .rdl files
--out <path> Path to .winmd, .rdl, or .rs file to generate
--filter <namespace> Namespaces to include or !exclude in output
--config <key=value> Override a configuration value
--format Format .rdl files only
--etc <path> File containing command line options
```

0 comments on commit 3a605cb

Please sign in to comment.