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
// src/lib.rs
//
// Copyright (C) 2023-2025 James Petersen <m@jamespetersen.ca>
// Licensed under Apache 2.0 OR MIT. See LICENSE-APACHE or LICENSE-MIT
//! This crate exists to provide a portable method to get any user's home
//! directory. The API is rather simple: there are two main functions,
//! [`home`] and [`my_home`]. The former can get the home directory
//! of any user provided you have their username. The latter can get the home
//! directory of the user executing this process.
//!
//! If all that is necessary is the home directory of the user executing this process,
//! then other crates may be better options, such as
//! [`directories`](https://crates.io/crates/directories). As well, using the home directory to find the
//! documents, downloads, pictures, etc. directories may not be accurate.
//!
//! This crate aims to work on both Windows and Unix systems. However,
//! Unix systems do not have a unified API. This crate may not work
//! on Unix systems which do not have the `getpwnam_r(3)`, `getpwuid_r(3)`,
//! and `getuid(2)` functions. This does not pose a problem on Linux and macOS.
//! As well, Windows has its own set of issues.
//! See [for Windows users](#for-windows-users).
//!
//! For Windows, the
//! [`windows`](https://docs.rs/homedir/latest/x86_64-pc-windows-msvc/homedir/windows/index.html)
//! module contains the implementation details. For Linux, macOS, and other Unix systems, the
//! [`unix`](https://docs.rs/homedir/latest/homedir/unix/index.html) module contains the
//! implementation details.
//!
//! # Usage
//! This crate is on [crates.io](https://crates.io/crates/homedir) and can be used by executing `cargo add homedir`
//! or adding the following to the dependencies in your `Cargo.toml` file.
//!
//! ```toml
//! [dependencies]
//! homedir = "0.3.6"
//! ```
//!
//! # Examples
//! ## Get the process' user's home directory.
//! ```no_run
//! use homedir::my_home;
//! use std::path::PathBuf;
//!
//! # fn main() -> Result<(), homedir::GetHomeError> {
//! // This assumes that the process' user has "/home/jpetersen" as home directory.
//! assert_eq!(
//! Some(PathBuf::from("/home/jpetersen".to_owned())),
//! my_home()?
//! );
//! # Ok(())
//! # }
//! ```
//!
//! ## Get an arbitrary user's home directory.
//! ```no_run
//! use homedir::home;
//! use std::path::PathBuf;
//!
//! # fn main() -> Result<(), homedir::GetHomeError> {
//! // This assumes there is a user named `Administrator` which has
//! // `C:\Users\Administrator` as a home directory.
//! assert_eq!(
//! Some(PathBuf::from("C:\\Users\\Administrator".to_owned())),
//! home("Administrator")?
//! );
//! assert!(home("NonExistentUser")?.is_none());
//! # Ok(())
//! # }
//! ```
//!
//! # Upgrading from 0.2.1 to 0.3
//! There is a major API restructuring in this version. `get_my_home` has been renamed to
//! [`my_home`] and `get_home` to [`home`]. As well, a cleaner implementation of a cross-platform
//! API has been written, with inspiration taken from the Rust standard library. The
//! [`UserIdentifier`] type now has a platform-agnostic implementation of the root of the crate.
//!
//! This version upgrade removes the `wmi` and `serde` dependencies which rendered this crate
//! larger on the Windows version.
//!
//! # For Windows Users
//! This crate uses the
//! [COM library](https://learn.microsoft.com/en-us/windows/win32/com/the-com-library)
//! to access the Windows Management Instrumentation for [`home`] (not [`my_home`]).
//! To use this library, it is required to call
//! [`CoInitializeEx`](https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-coinitializeex)
//! (or `CoInitialize`), which has
//! [some issues](https://github.com/microsoft/windows-rs/issues/1169). When using this crate,
//! this will only *possibly* present an issue to programs that also use the COM library.
//!
//! Referencing the solution provided in the linked issue, the
//! way that this crate uses the COM library is as follows. It will try to
//! [create an
//! instance](https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cocreateinstance).
//! If this fails because the COM library is not yet initialized, it will call `CoInitializeEx`
//! using `COINIT_MULTITHREADED`, and it will not call `CoUninitialize` later. This will interfere
//! with libraries that use `OleInitialize`, which requires `COINIT_APARTMENTTHREADED`.
//!
//! To prevent these issues, the feature `windows-coinitialize` can be used. If it is specified,
//! then the program will call `CoInitializeEx` if `CoCreateInstance` fails. It is specified by
//! default. If you opt not to use it, in order to call
//! [`home`], it will be necessary to first call `CoInitializeEx` with whatever parameters are
//! required, or initialize the other libraries that use it (for example
//! [`wmi`](https://crates.io/crates/wmi)) first.
//!
//! Finally, this program has been tested on a regular Windows 11 installation. It has
//! not been tested within any Active Directory Windows installation, and the implementation does
//! not test for this or try to account for it in any way. If it does work on these, it will likely
//! return the local profile path of the specified user.
use fmt;
use PathBuf;
use cfg_if;
cfg_if!
/// This structure represents a user's identifier.
///
/// # Example
/// ```no_run
/// use homedir::UserIdentifier;
///
/// # fn main() -> Result<(), homedir::GetHomeError> {
/// if let Some(identifier) = UserIdentifier::with_username("Administrator")? {
/// println!("{:?}", identifier.to_home()?);
/// }
/// # Ok(())
/// # }
/// ```
;
/// This structure contains the error type returned by the functions within this crate.
;
/// Get the home directory of an arbitrary user. This will return the `Err` variant
/// if an error occurs. If no user with the given username can be found, `Ok(None)` is returned
/// instead.
///
/// There is an example of the usage of this function in the [crate documentation](crate).
/// Get the home directory of the process' current user.
///
/// There is an example of the usage of this function in the [crate documentation](crate).