Skip to content

Commit a1ca334

Browse files
authored
Merge pull request #116 from Legend-Master/canonicalize-ILCreateFromPathW
fix(windows): pass canonicalized path to `ILCreateFromPathW`
2 parents 335146b + c84cade commit a1ca334

File tree

2 files changed

+20
-11
lines changed

2 files changed

+20
-11
lines changed

.github/workflows/cross-platform-testing.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ jobs:
3535
rust: nightly
3636
target: x86_64-apple-darwin
3737
- build: win-msvc
38-
os: windows-2019
38+
os: windows-2022
3939
rust: stable
4040
target: x86_64-pc-windows-msvc
4141
- build: win-gnu
42-
os: windows-2019
42+
os: windows-2022
4343
rust: stable
4444
target: x86_64-pc-windows-gnu
4545
- build: win32-gnu

src/windows.rs

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,11 @@ fn wrap_in_quotes<T: AsRef<OsStr>>(path: T) -> OsString {
3838

3939
#[cfg(feature = "shellexecute-on-windows")]
4040
pub fn that_detached<T: AsRef<OsStr>>(path: T) -> std::io::Result<()> {
41-
use std::path::Path;
42-
4341
let path = path.as_ref();
4442
let is_dir = std::fs::metadata(path).map(|f| f.is_dir()).unwrap_or(false);
4543

4644
if is_dir {
47-
let path = dunce::simplified(Path::new(path));
48-
let path = wide(path);
49-
unsafe { ffi::CoInitialize(std::ptr::null()) };
50-
let folder = unsafe { ffi::ILCreateFromPathW(path.as_ptr()) };
51-
if unsafe { SHOpenFolderAndSelectItems(folder, Some(&[folder]), 0) }.is_ok() {
45+
if shell_open_folder(path).is_ok() {
5246
return Ok(());
5347
}
5448
};
@@ -73,6 +67,20 @@ pub fn that_detached<T: AsRef<OsStr>>(path: T) -> std::io::Result<()> {
7367
unsafe { ShellExecuteExW(&mut info) }
7468
}
7569

70+
#[cfg(feature = "shellexecute-on-windows")]
71+
fn shell_open_folder(path: &OsStr) -> Result<(), std::io::Error> {
72+
let path = dunce::canonicalize(path)?;
73+
let path = wide(path);
74+
unsafe { ffi::CoInitialize(std::ptr::null()) };
75+
let folder = unsafe { ffi::ILCreateFromPathW(path.as_ptr()) };
76+
if folder.is_null() {
77+
return Err(std::io::Error::last_os_error());
78+
}
79+
let result = unsafe { SHOpenFolderAndSelectItems(folder, Some(&[folder]), 0) };
80+
unsafe { ffi::ILFree(folder) };
81+
result
82+
}
83+
7684
#[cfg(feature = "shellexecute-on-windows")]
7785
pub fn with_detached<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> std::io::Result<()> {
7886
let app = wide(app.into());
@@ -156,10 +164,10 @@ mod ffi {
156164
/// <https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow>
157165
pub const SW_SHOWNORMAL: i32 = 1;
158166

159-
/// Null-terminated UTF-16 encoding of `explore`.
167+
/// Null-terminated UTF-16 encoding of `explore`.
160168
pub const EXPLORE: *const u16 = [101, 120, 112, 108, 111, 114, 101, 0].as_ptr();
161169

162-
/// Null-terminated UTF-16 encoding of `folder`.
170+
/// Null-terminated UTF-16 encoding of `folder`.
163171
pub const FOLDER: *const u16 = [102, 111, 108, 100, 101, 114, 0].as_ptr();
164172

165173
// Taken from https://docs.rs/windows-sys/latest/windows_sys/
@@ -214,6 +222,7 @@ mod ffi {
214222
apidl: *const *const ITEMIDLIST,
215223
dwflags: u32,
216224
) -> i32;
225+
pub fn ILFree(pidl: *const ITEMIDLIST) -> i32;
217226
}
218227

219228
#[link(name = "ole32")]

0 commit comments

Comments
 (0)