1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
//! Windows desktop helpers for Rust apps.
//!
//! `win-desktop-utils` wraps a focused set of Windows desktop chores that many
//! GUI, tray, installer-adjacent, and local utility apps need, while keeping raw
//! Win32 shell, shortcut, mutex, known-folder, and elevation APIs out of the
//! application code that uses them.
//!
//! The low-level helpers stay available as small functions, and [`DesktopApp`]
//! keeps common app startup and app-data setup in one place.
//! On non-Windows targets, the public API still compiles and operational helpers
//! return [`Error::Unsupported`].
//!
//! # When To Use This
//!
//! | Need | Start with | Feature |
//! | --- | --- | --- |
//! | App identity, app-data paths, and one-instance startup | [`DesktopApp`] | `app` |
//! | Per-user local or roaming app-data directories | [`ensure_local_app_data`] or [`ensure_roaming_app_data`] | `paths` |
//! | Current-session single-instance behavior | [`single_instance`] | `instance` |
//! | Global or builder-style single-instance behavior | [`single_instance_with_scope`] or [`SingleInstanceOptions`] | `instance` |
//! | Open files, folders, URLs, Properties, or print verbs | [`open_with_default`], [`open_url`], or [`open_with_verb`] | `shell` |
//! | Select a path in Explorer | [`reveal_in_explorer`] | `shell` |
//! | Move files or folders to the Recycle Bin | [`move_to_recycle_bin`] or [`move_paths_to_recycle_bin`] | `recycle-bin` |
//! | Create `.lnk` or `.url` shortcuts | [`create_shortcut`] or [`create_url_shortcut`] | `shortcuts` |
//! | Check or request administrator elevation | [`is_elevated`], [`restart_as_admin`], or [`run_as_admin`] | `elevation` |
//!
//! This crate is Windows-first. Non-Windows builds provide stubs so cross-platform
//! applications can depend on the crate without wrapping the dependency itself in
//! `cfg(windows)`.
//!
//! # When Not To Use This
//!
//! Use the `windows` crate directly when you need broad Win32 coverage, custom
//! flags, direct COM object ownership, or APIs outside this crate's small
//! desktop-app scope. Use a GUI framework when you need windows, controls,
//! rendering, menus, or native widgets.
//!
//! # Quick Start
//!
//! ```
//! fn main() -> Result<(), win_desktop_utils::Error> {
//! let app = win_desktop_utils::DesktopApp::new(format!(
//! "demo-app-{}",
//! std::process::id()
//! ))?;
//!
//! let _guard = match app.single_instance()? {
//! Some(guard) => guard,
//! None => {
//! println!("already running");
//! return Ok(());
//! }
//! };
//!
//! let local = app.ensure_local_data_dir()?;
//! assert!(local.exists());
//!
//! Ok(())
//! }
//! ```
//!
//! # Feature Flags
//!
//! Default features enable the full API. Consumers can opt out and select only
//! the modules they need:
//!
//! ```toml
//! [dependencies]
//! win-desktop-utils = { version = "0.5", default-features = false, features = ["paths", "instance"] }
//! ```
//!
//! Cross-platform applications can also keep the dependency Windows-only:
//!
//! ```toml
//! [target.'cfg(windows)'.dependencies]
//! win-desktop-utils = "0.5"
//! ```
//!
//! Available features:
//!
//! - `app`: [`DesktopApp`] facade 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`: `.lnk` and `.url` shortcut helpers.
//! - `elevation`: elevation detection and shell-based relaunch helpers.
//!
//! The default feature set is intentionally broad for convenience. Feature flags
//! control this crate's public modules; the underlying `windows` dependency uses
//! one shared set of Win32 bindings when any Windows API feature is enabled.
//! CI checks no-default, each individual public feature, and every pairwise
//! public feature combination.
//!
//! # Common Workflows
//!
//! Startup guard plus app-data directory:
//!
//! ```
//! let app = win_desktop_utils::DesktopApp::new(format!(
//! "workflow-demo-{}",
//! std::process::id()
//! ))?;
//! let _guard = app.single_instance()?.expect("first instance");
//! let config_dir = app.ensure_local_data_dir()?;
//! assert!(config_dir.exists());
//! # Ok::<(), win_desktop_utils::Error>(())
//! ```
//!
//! Create a shortcut:
//!
//! ```no_run
//! let shortcut = std::env::current_dir()?.join("notepad.lnk");
//! let options = win_desktop_utils::ShortcutOptions::new()
//! .description("Open Notepad");
//! win_desktop_utils::create_shortcut(&shortcut, r"C:\Windows\notepad.exe", &options)?;
//! # Ok::<(), Box<dyn std::error::Error>>(())
//! ```
//!
//! Relaunch the current executable as administrator:
//!
//! ```no_run
//! use std::ffi::OsString;
//!
//! if !win_desktop_utils::is_elevated()? {
//! win_desktop_utils::restart_as_admin(&[OsString::from("--elevated")])?;
//! }
//! # Ok::<(), win_desktop_utils::Error>(())
//! ```
//!
//! # Behavior And Side Effects
//!
//! - [`open_with_default`] requires a non-empty existing path.
//! - [`open_with_verb`] uses `ShellExecuteW` with the requested shell verb.
//! - [`show_properties`] and [`print_with_default`] are small shell-verb wrappers.
//! - [`open_url`] trims surrounding whitespace before delegating to the Windows shell.
//! - [`reveal_in_explorer`] requires an existing path and launches `explorer.exe`.
//! - [`open_containing_folder`] opens the existing path's parent directory.
//! - [`move_to_recycle_bin`] requires an absolute existing path and uses `IFileOperation`
//! on a dedicated STA thread for recycle-bin behavior.
//! - [`move_paths_to_recycle_bin`] validates all paths before starting one shell
//! recycle-bin operation.
//! - [`empty_recycle_bin`] permanently empties the Recycle Bin without showing shell UI.
//! - [`create_shortcut`] uses `IShellLinkW` on a dedicated STA thread.
//! - [`roaming_app_data`] and [`local_app_data`] resolve their base directories via
//! `SHGetKnownFolderPath` after rejecting empty or NUL-containing app names.
//! - [`single_instance`] uses a `Local\...` named mutex, so the lock is scoped to the
//! current Windows session, and `app_id` cannot contain backslashes.
//! - [`single_instance_with_scope`] can opt into either the current-session or global
//! mutex namespace.
//! - [`restart_as_admin`] starts a new elevated instance of the current executable,
//! does not terminate the current process, and rejects arguments containing NUL bytes.
//! - [`run_as_admin`] and [`run_with_verb`] launch arbitrary commands through
//! `ShellExecuteW`.
//!
//! # Runtime Model
//!
//! The crate does not start a background runtime, async executor, telemetry, or
//! global worker. Most helpers validate input and then delegate to Windows. The
//! shortcut and Recycle Bin helpers use short-lived STA worker threads for COM
//! operations that require apartment-threaded shell APIs.
//!
//! # Stability
//!
//! The minimum supported Rust version is 1.82. Public API compatibility is checked
//! in CI with `cargo-semver-checks`, and dependency policy is checked with
//! `cargo-deny`.
pub use ;
pub use DesktopApp;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use DesktopApp;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;