From 3b48ee084300ba883bed11259d978fa989ffaed8 Mon Sep 17 00:00:00 2001 From: Brian Bowman Date: Sun, 19 Mar 2023 22:38:12 -0500 Subject: [PATCH] Improve `open()`'s Windows path handling Forward slash separators in relative paths are now accepted. --- opener/Cargo.toml | 1 + opener/src/windows.rs | 16 ++++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/opener/Cargo.toml b/opener/Cargo.toml index 6046c69..403ab8d 100644 --- a/opener/Cargo.toml +++ b/opener/Cargo.toml @@ -33,6 +33,7 @@ dbus = { version = "0.9", optional = true, features = ["vendored"] } url = { version = "2", optional = true } [target.'cfg(windows)'.dependencies] +normpath = "1" winapi = { version = "0.3", features = ["shellapi"] } dunce = { version = "1", optional = true } diff --git a/opener/src/windows.rs b/opener/src/windows.rs index 44ec1e8..dbdc943 100644 --- a/opener/src/windows.rs +++ b/opener/src/windows.rs @@ -1,6 +1,8 @@ use crate::OpenError; +use normpath::PathExt; use std::ffi::OsStr; use std::os::windows::ffi::OsStrExt; +use std::path::PathBuf; use std::{io, ptr}; use winapi::ctypes::c_int; use winapi::um::shellapi::ShellExecuteW; @@ -11,6 +13,20 @@ mod reveal; pub(crate) use self::reveal::reveal; pub(crate) fn open(path: &OsStr) -> Result<(), OpenError> { + let Err(first_error) = open_helper(path) else { + return Ok(()); + }; + + match PathBuf::from(path).normalize() { + Ok(normalized) => match open_helper(normalized.as_os_str()) { + Ok(()) => Ok(()), + Err(_second_error) => Err(first_error), + }, + Err(_) => Err(first_error), + } +} + +pub(crate) fn open_helper(path: &OsStr) -> Result<(), OpenError> { const SW_SHOW: c_int = 5; let path = convert_path(path).map_err(OpenError::Io)?;