WSLPlugins-rs is a Rust framework for building WSL plugins. It wraps the raw WSL plugin API with safer, more idiomatic Rust types and provides a procedural macro for generating plugin entry points and hook wiring. The project is intended for Windows hosts that load plugins through WSL. It includes:
- a runtime crate:
wslplugins-rs - a proc-macro crate:
wslplugins-macro - examples that build real plugin DLLs
- Safe and ergonomic wrappers around the WSL plugin API
- A
#[wsl_plugin_v1(...)]macro that generates the exported entry points - Support for WSL metadata, session information, and command execution
- Examples that can be built, signed, and loaded into WSL
Install the following tools on Windows:
- Rust stable and Cargo
- PowerShell
- OpenSSL for certificate generation in the signing script
SignTool.exefrom the Windows SDK
Notes:
SignTool.exeis easiest to access from a Visual Studio Developer Command Prompt or a shell where the Windows SDK tools are onPATH.sign-plugin.ps1requires an elevated PowerShell session.- Running the signing step with
-Trustinstalls the generated certificate into the local machine trusted root store.
The workspace is organized around a small public API surface and separate macro implementation crates:
wslplugins-rs: the main framework crate, with safe wrappers around the WSL plugin API, shared plugin context, typed identifiers, and plugin traits.wslplugins-macro: the procedural macro crate re-exported bywslplugins-rswhen themacrofeature is enabled.wslplugins-macro-core: the internal parsing and code generation implementation used by the procedural macro.wslplugins-macro-tests: compile-time tests for macro-generated plugin code.
This split keeps plugin authors focused on wslplugins-rs, while the macro parsing and generated WSL entry-point wiring stay isolated in internal crates.
Add the crate with the macro feature:
[dependencies]
wslplugins-rs = { version = "0.1.0-beta.3", features = ["macro"] }Then implement a plugin:
use wslplugins_rs::prelude::*;
pub(crate) struct MyPlugin {
context: &'static WSLContext,
}
#[wsl_plugin_v1(2, 0, 5)]
impl WSLPluginV1 for MyPlugin {
fn try_new(context: &'static WSLContext) -> WinResult<Self> {
Ok(Self { context })
}
}The macro feature re-exports the wsl_plugin_v1 attribute and generates the WSL entry points for a WSLPluginV1 implementation.
Use ApiV1::new_command to build and execute a Linux command from a plugin session.
use wslplugins_rs::api::{ApiV1, WSLCommandExecution};
use wslplugins_rs::SessionID;
fn run_version(api: &ApiV1) -> Result<(), Box<dyn std::error::Error>> {
let stream = api
.new_command(SessionID::from(0), "/bin/cat")
.with_arg("/proc/version")
.execute()?;
drop(stream);
Ok(())
}Notes:
- Program paths must be Linux UTF-8 paths such as
/bin/echo argv[0]defaults to the program path and can be overridden withwith_arg0with_distribution_idtargets a specific user distributionexecute()returns aTcpStreamconnected to process stdin/stdout- stderr is forwarded to Linux
dmesg
Two example plugins are included:
examples/minimal: a close Rust translation of Microsoft's sample pluginexamples/dist-info: a plugin focused on distribution metadata and tracing
Build one of them in release mode:
cargo build --release -p minimalor:
cargo build --release -p dist-infoThe resulting plugin DLLs are produced in target\release\.
Sign the built DLL with the provided PowerShell script:
.\sign-plugin.ps1 -PluginPath .\target\release\minimal.dll -Trustor:
.\sign-plugin.ps1 -PluginPath .\target\release\dist_info.dll -TrustIf you do not want to install the certificate automatically, omit -Trust.
Microsoft's WSL plugin documentation also requires Windows test signing for test-signed plugin DLLs. If WSL rejects a locally signed plugin with TRUST_E_NOSIGNATURE, enable test signing on the test machine and reboot if required:
Bcdedit.exe -set TESTSIGNING ONRegister the signed DLL in the WSL plugins registry key:
reg.exe add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss\Plugins" /v minimal /d "C:\path\to\wslplugins-rs\target\release\minimal.dll" /t REG_SZAdjust the registry value name and DLL path for the plugin you want to load.
Restart the WSL service after registration, then run a WSL command to load the plugin:
Stop-Service -Name "wslservice" -Force
wsl.exe echo "test"After loading the plugin:
- inspect the log output produced by the example
- verify the DLL path in the registry
- confirm the DLL was signed successfully
The minimal example writes to C:\wsl-plugin-demo.txt.
The repository release workflow is centered on these commands:
cargo test --workspace --all-features
cargo clippy --workspace --all-targets --all-features
cargo fmt --all -- --check
cargo publish --workspace --dry-runContributions are welcome. See CONTRIBUTING.md for branch, validation, and pull request guidance.
Please report security issues privately. See SECURITY.md.
Licensed under either MIT or Apache-2.0.