Ergonomic, idiomatic Rust wrappers for Windows APIs.
windows-erg provides safe, high-level APIs on top of windows-rs for common Windows system programming tasks.
See CHANGELOG.md for the current documented release snapshot and future release notes.
For contributors and coding agents: read CONTEXT.md first.
- Safe handle lifecycle via RAII
- Structured error model
- Type-safe identifiers and API surfaces
- Builder-style configuration where useful
- Buffer-reuse variants for allocation-sensitive paths
Add to Cargo.toml:
[dependencies]
windows-erg = "0.1"- Windows 10+
- Rust 1.90+
- Targets:
- x86_64-pc-windows-msvc
- aarch64-pc-windows-msvc
- CI validates
aarch64-pc-windows-msvcusing cross-target compile checks. - Runtime behavior should be validated on native Windows ARM64 hardware/runners.
- process: process and thread enumeration, process tree operations, module inspection
- desktop: desktop window enumeration, tray icon lifecycle, tray balloon notifications
- registry: key/value operations with ergonomic typed access
- evt: Windows Event Log query and rendering
- etw: ETW session and event consumption support
- proxy: system and URL-specific proxy resolution
- mitigation: process mitigation query/apply helpers
- file: raw file operations
- service: Windows Service Control Manager query/control/enumeration
- security, pipes: security and IPC primitives
use windows_erg::process::Process;
for p in Process::list()? {
println!("{} {}", p.id().as_u32(), p.name());
}
# Ok::<(), windows_erg::Error>(())use windows_erg::registry::{Hive, RegistryKey};
let key = RegistryKey::open(
Hive::LocalMachine,
r"SOFTWARE\Microsoft\Windows\CurrentVersion",
)?;
let value: String = key.get_value("ProgramFilesDir")?;
println!("{}", value);
# Ok::<(), windows_erg::Error>(())use windows_erg::evt::EventLog;
let log = EventLog::open("System")?;
let events = log.query().level("Error").execute()?;
println!("events: {}", events.len());
# Ok::<(), windows_erg::Error>(())use windows_erg::etw::{EventTrace, SystemProvider};
let mut trace = EventTrace::builder("ProcessMonitor")
.system_provider(SystemProvider::Process)
.with_decoded_stream()
.start()?;
let mut decoded = Vec::with_capacity(128);
let count = trace.next_batch_decoded(&mut decoded)?;
println!("decoded events: {}", count);
trace.stop()?;
# Ok::<(), windows_erg::Error>(())use windows_erg::security::{
AccessMask, ApplyMode, PermissionEditor, PermissionTarget, Sid,
};
let target = PermissionTarget::file(r"C:\\Temp\\example.txt".to_string());
let users = Sid::parse("S-1-5-32-545")?; // Built-in Users
let plan = PermissionEditor::new()
.grant(users, AccessMask::from_bits(0x120089))
.build()?;
let result = plan.execute_against_target(&target, ApplyMode::DryRunDiff)?;
println!("added ACEs: {}", result.diff.added.len());
# Ok::<(), windows_erg::Error>(())Some operations require administrator privileges:
- ETW session management
- raw file operations
- writes under protected registry hives
- operations on protected/high-integrity processes
APIs return structured permission/access errors when denied.
- ETW supports raw, decoded, or dual stream modes.
- Kernel providers require elevated privileges and use the kernel logger session.
- You cannot mix kernel system providers and user-mode provider GUIDs in a single ETW session.
- Use bounded channel capacity and batch draining for sustained high-volume traces.
See examples:
- examples/etw_process_monitor.rs
- examples/etw_network_monitor.rs
- examples/etw_multi_provider.rs
- examples/etw_decoded_events.rs
- Security descriptor APIs support both file and registry targets.
- Use dry-run first to inspect ACL diffs before applying changes.
- Descriptor model includes owner, group, DACL, and typed ACE entries.
- Convenience APIs are available in file and registry modules for common read/write/apply flows.
See examples:
- examples/security_permissions.rs
- examples/pipes_list.rs
- examples/process_basics.rs
- examples/process_monitoring.rs
- examples/process_tree.rs
- examples/process_mitigation.rs
- examples/desktop_windows.rs
- examples/desktop_tray_notification.rs
- examples/registry_basics.rs
- examples/registry_operations.rs
- examples/registry_write.rs
- examples/evt_query_basic.rs
- examples/evt_streaming.rs
- examples/etw_process_monitor.rs
- examples/etw_network_monitor.rs
- examples/proxy_system.rs
- examples/proxy_for_url.rs
- examples/raw_file_copy.rs
- examples/service_basics.rs
- examples/service_enumerate.rs
- examples/security_permissions.rs
- examples/system_power_control.rs
Run one example:
cargo run --example process_basicsFallible operations return:
Result<T, windows_erg::Error>The crate uses structured error types (see src/error.rs), not string-only error payloads.
Examples are organized into three buckets based on privilege level, runtime behavior, and side effects.
When adding a new example, update the example lists in this README. If the example is safe and stable for CI/CD, also place it in the appropriate auto-run bucket.
Quick sanity check for core APIs. No side effects, no special privileges needed:
$examples = @(
"process_basics", "process_metrics", "process_mitigation", "process_monitoring",
"desktop_windows", "system_snapshot", "wait_multi_object", "security_permissions",
"registry_basics", "registry_convenience", "registry_enumerate", "registry_operations",
"registry_safe_access", "registry_write", "proxy_system", "proxy_for_url", "service_enumerate"
)
foreach ($ex in $examples) {
cargo run --example $ex 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) { Write-Host "FAILED: $ex" -ForegroundColor Red; break }
Write-Host "PASSED: $ex" -ForegroundColor Green
}Event log examples with results that vary by system state and access level:
# These run without admin but may return 0 events depending on log state
cargo run --example evt_custom_parsing
cargo run --example evt_filter
cargo run --example evt_streaming
# Requires admin (Security log access)
cargo run --example evt_query_basic
# Requires serde feature flag
cargo run --example evt_serde --features serdeRun these individually in separate terminal sessions.
Long-running ETW monitors — press Ctrl+C to stop (require admin):
cargo run --example etw_process_monitor
cargo run --example etw_registry_monitor
cargo run --example etw_network_monitor
cargo run --example etw_multi_provider
cargo run --example etw_decoded_events
cargo run --example etw_user_mode_providerSide-effect examples — modify state or require elevated privileges:
cargo run --example desktop_tray_notification # 5s UI notification
cargo run --example process_spawn_parented # spawns notepad as explorer child
cargo run --example process_tree # spawns and kills test process
cargo run --example process_wait_any # multiple timeout scenarios (~8s)
cargo run --example service_basics # may restart/stop Spooler service
cargo run --example etw_stop_with_wait # admin + kernel provider required
cargo run --example raw_file_copy # admin + raw file I/O required
cargo run --example system_power_control -- restart --force --timeout 60 --execute # admin + triggers machine restart/shutdownFastest way to confirm nothing is broken:
cargo check
cargo test --lib
cargo run --example system_snapshot
cargo run --example process_basics
cargo run --example registry_basicsEnable serde support for event log serialization:
[dependencies]
windows-erg = { version = "0.1", features = ["serde"] }- API docs: https://docs.rs/windows-erg
- Project coding context: CONTEXT.md
Thank you for your interest in contributing!
For comprehensive contribution guidelines, code standards, and the complete CI/CD checklist that all changes must pass, see CONTRIBUTING.md.
Quick workflow:
- Read CONTEXT.md — critical coding patterns and standards
- Read CONTRIBUTING.md — CI checks and submission workflow
- Follow the code review checklist in CONTRIBUTING.md
- Run local pre-push validation (see CONTRIBUTING.md)
- Submit PR
For questions, open an issue before submitting code.
MIT