win-desktop-utils
Windows desktop helpers for Rust apps.
win-desktop-utils wraps the small but fiddly Windows desktop tasks that show up in real apps: shell opening, Explorer reveal, Recycle Bin moves, shortcuts, app-data paths, single-instance locks, and elevation prompts.
Use the low-level helpers directly, or start with DesktopApp for the common “app identity, app-data directory, and single-instance guard” workflow.
Scope
This crate currently provides helpers to:
- open an existing file or directory with the default Windows handler
- open an existing file or directory with an explicit Windows shell verb
- open a URL with the default browser or registered handler
- reveal an existing path in Explorer
- move an existing file or directory to the Recycle Bin
- empty the Recycle Bin silently
- create Windows
.lnkshortcuts - create Internet Shortcut
.urlfiles - enforce single-instance behavior with a named mutex
- configure single-instance behavior with builder-style options
- resolve per-user roaming and local app-data paths
- create per-user roaming and local app-data paths if needed
- check whether the current process is elevated
- relaunch the current executable as administrator
- launch arbitrary commands through shell verbs such as
openorrunas
This crate is Windows-first. On non-Windows targets, the public API still
compiles and operational helpers return Error::Unsupported.
Installation
[]
= "0.5"
Default features enable the full API. To keep a dependency focused, disable defaults and opt into only the modules you need:
[]
= { = "0.5", = false, = ["paths", "instance"] }
For crates that only need these helpers in Windows-specific code, use a target-specific dependency:
[]
= "0.5"
For cross-platform crates that want the same public symbols available everywhere,
use a normal dependency and handle Error::Unsupported on non-Windows targets.
Quick Start
Feature Flags
app:DesktopAppfacade for app-data and single-instance startup.paths: per-user local and roaming app-data helpers.instance: named-mutex single-instance helpers.shell: shell opening, URL, Explorer, and shell-verb helpers.recycle-bin: Recycle Bin move and empty helpers.shortcuts:.lnkand.urlshortcut helpers.elevation: elevation detection and shell-based relaunch helpers.
Current API
DesktopAppopen_with_default(path)open_with_verb(verb, path)show_properties(path)print_with_default(path)open_url(url)reveal_in_explorer(path)open_containing_folder(path)move_to_recycle_bin(path)move_paths_to_recycle_bin(paths)empty_recycle_bin()empty_recycle_bin_for_root(root_path)create_shortcut(shortcut_path, target_path, options)create_url_shortcut(shortcut_path, url)single_instance(app_id)single_instance_with_scope(app_id, scope)single_instance_with_options(options)roaming_app_data(app_name)local_app_data(app_name)ensure_roaming_app_data(app_name)ensure_local_app_data(app_name)is_elevated()restart_as_admin(args)run_as_admin(executable, args)run_with_verb(verb, executable, args)InstanceScope::{CurrentSession, Global}SingleInstanceOptionsShortcutOptionsShortcutIcon
Cookbook
The docs/cookbook.md file has copy-paste recipes for:
- starting a single-instance app
- creating local and roaming app-data folders
- opening files, URLs, folders, and Properties
- creating
.lnkand.urlshortcuts - relaunching as administrator
- moving files to the Recycle Bin
Additional guides:
docs/adoption.md: integration notes for common app shapesdocs/which-api.md: pick the right helper for a taskdocs/side-effects.md: user-visible behavior and safety notesdocs/compatibility.md: OS, Rust, feature, and non-Windows build policydocs/design.md: project scope and API acceptance rulesdocs/testing.md: test structure and expectations
Examples
The examples/ directory includes runnable samples for:
- app-data path lookup and creation
- URL opening and Explorer reveal helpers
- shell verb execution for files and directories
- Recycle Bin integration
- shortcut creation
- elevation checks and relaunch
- launching arbitrary commands through shell verbs
- single-instance enforcement
- single-instance enforcement across all sessions
- builder-style single-instance options
- cohesive
DesktopAppstartup flow
Run any example with:
cargo run --example single_instance
Why Not Use windows Directly?
Use windows directly when you need broad Win32 coverage, custom flags, direct
COM object ownership, or APIs outside this crate's scope.
Use win-desktop-utils when you want a small, documented layer for common
desktop app chores with validation, Rust-friendly builders, examples, and a
stable public API.
Alternatives And Scope
This crate is not a GUI framework, installer, updater, service framework, or cross-platform desktop abstraction. It works well alongside GUI frameworks and installer tools by handling a small set of Windows desktop tasks that application code often needs after startup or in response to user actions.
Error behavior
The crate exposes a small public error type with explicit path-related cases.
Notable error distinctions include:
Error::InvalidInput(...)for empty or malformed inputError::PathNotAbsolutewhen an operation requires an absolute pathError::PathDoesNotExistwhen an operation requires an existing pathError::WindowsApi { .. }when a Win32 or shell operation reports failureError::Io(...)for underlying I/O failuresError::Unsupported(...)for Windows operations called on non-Windows targets
Behavior notes
open_with_defaultrequires a non-empty existing path.open_with_verbrequires a non-empty existing path and a non-empty shell verb such asopenorproperties.show_propertiesandprint_with_defaultare convenience wrappers over shell verbs.open_urltrims surrounding whitespace before delegating to the Windows shell.reveal_in_explorerrequires an existing path and launchesexplorer.exe.open_containing_folderrequires an existing path and opens its parent directory.move_to_recycle_binrequires an absolute existing path and usesIFileOperationon a dedicated STA thread for recycle-bin behavior.move_paths_to_recycle_binvalidates every path before starting one recycle-bin shell operation.empty_recycle_binandempty_recycle_bin_for_rootpermanently empty Recycle Bin contents without showing shell UI.create_shortcutrequires an absolute.lnkpath, an existing output parent directory, and an existing absolute target path.create_url_shortcutrequires an absolute.urlpath and rejects line breaks in URLs to avoid malformed shortcut files.roaming_app_dataandlocal_app_dataresolve the base directory viaSHGetKnownFolderPath.single_instanceuses aLocal\...named mutex, so the lock is scoped to the current Windows session.single_instance_with_scopecan opt into either the current-session (Local\...) or global (Global\...) namespace.SingleInstanceOptionsprovides a small builder around single-instance app ID and scope selection.single_instancerejects backslashes inapp_idbecause Windows reserves them for kernel-object namespaces such asLocal\andGlobal\.- Keep the returned
InstanceGuardalive for as long as the process should own the single-instance lock. restart_as_adminstarts a new elevated instance of the current executable and does not terminate the current process.run_as_adminstarts an arbitrary command with therunasshell verb and may trigger UAC.restart_as_admin,run_as_admin, andrun_with_verbreject arguments containing NUL bytes.- On non-Windows targets, public APIs compile and Windows operations return
Error::Unsupported.
Quality
The crate includes:
- automated tests for validation and single-instance behavior
- unit tests covering argument quoting and input normalization edge cases
- doctest examples in the public modules
- rustdoc lint checks for public documentation quality
cargo xtaskautomation for docs, feature, package, and release checks- Windows CI via GitHub Actions for MSRV, formatting, tests, clippy, examples, doctests, docs, packaging, dependency policy, and semver checks
- non-Windows CI checks that the public API stubs compile and return unsupported errors
- documentation link checks for local Markdown links
- docs published on docs.rs
The minimum supported Rust version is 1.82, matching the current windows crate dependency floor.
Support Policy
- Supported OS family: Windows 10 and Windows 11.
- Non-Windows targets compile public API stubs that return
Error::Unsupported. - Supported Rust: 1.82 and newer.
- Public API compatibility is checked with
cargo-semver-checks. - Dependency advisories, licenses, duplicate versions, and sources are checked with
cargo-deny.
Links
- Crates.io: https://crates.io/crates/win-desktop-utils
- Docs: https://docs.rs/win-desktop-utils
- Repository: https://github.com/funwithcthulhu/win-desktop-utils
- Changelog: https://github.com/funwithcthulhu/win-desktop-utils/blob/main/CHANGELOG.md
- Cookbook: https://github.com/funwithcthulhu/win-desktop-utils/blob/main/docs/cookbook.md
- API guide: https://github.com/funwithcthulhu/win-desktop-utils/blob/main/docs/which-api.md
- Adoption notes: https://github.com/funwithcthulhu/win-desktop-utils/blob/main/docs/adoption.md
- Compatibility: https://github.com/funwithcthulhu/win-desktop-utils/blob/main/docs/compatibility.md
- Design contract: https://github.com/funwithcthulhu/win-desktop-utils/blob/main/docs/design.md
- Testing guide: https://github.com/funwithcthulhu/win-desktop-utils/blob/main/docs/testing.md
- Roadmap: https://github.com/funwithcthulhu/win-desktop-utils/blob/main/ROADMAP.md