mirror of
https://github.com/tauri-apps/plugins-workspace.git
synced 2026-05-27 13:22:26 +02:00
feat(shell): add show_item_in_dir api
This commit is contained in:
@@ -27,6 +27,15 @@ pub enum Error {
|
||||
/// JSON error.
|
||||
#[error(transparent)]
|
||||
Json(#[from] serde_json::Error),
|
||||
/// API not supported on the current platform
|
||||
#[error("API not supported on the current platform")]
|
||||
UnsupportedPlatform,
|
||||
#[error(transparent)]
|
||||
#[cfg(windows)]
|
||||
Win32Error(#[from] windows::core::Error),
|
||||
/// Path doesn't have a parent.
|
||||
#[error("Path doesn't have a parent: {0}")]
|
||||
NoParent(PathBuf),
|
||||
}
|
||||
|
||||
impl Serialize for Error {
|
||||
|
||||
@@ -64,6 +64,10 @@ impl<R: Runtime> Shell<R> {
|
||||
pub fn open(&self, path: impl Into<String>, with: Option<open::Program>) -> Result<()> {
|
||||
open::open(&self.open_scope, path.into(), with).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn show_item_in_directory<P: AsRef<Path>>(&self, p: P) -> Result<()> {
|
||||
open::show_item_in_directory(p)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ShellExt<R: Runtime> {
|
||||
|
||||
@@ -9,6 +9,22 @@ use serde::{Deserialize, Deserializer};
|
||||
use crate::scope::OpenScope;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[cfg(windows)]
|
||||
#[path = "windows.rs"]
|
||||
mod platform;
|
||||
#[cfg(target_os = "macos")]
|
||||
#[path = "macos.rs"]
|
||||
mod platform;
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
#[path = "linux.rs"]
|
||||
mod platform;
|
||||
|
||||
/// Program to use on the [`open()`] call.
|
||||
pub enum Program {
|
||||
/// Use the `open` program.
|
||||
@@ -120,3 +136,29 @@ impl Program {
|
||||
pub fn open<P: AsRef<str>>(scope: &OpenScope, path: P, with: Option<Program>) -> crate::Result<()> {
|
||||
scope.open(path.as_ref(), with).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn show_item_in_directory<P: AsRef<std::path::Path>>(p: P) -> crate::Result<()> {
|
||||
let p = p.as_ref().canonicalize()?;
|
||||
|
||||
#[cfg(any(
|
||||
windows,
|
||||
target_os = "maco",
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
return platform::show_item_in_directory(p);
|
||||
|
||||
#[cfg(not(any(
|
||||
windows,
|
||||
target_os = "maco",
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
target_os = "freebsd",
|
||||
target_os = "netbsd",
|
||||
target_os = "openbsd"
|
||||
)))]
|
||||
Err(crate::Error::UnsupportedPlatform)
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
use std::{ffi::OsString, path::PathBuf};
|
||||
|
||||
use windows::{
|
||||
core::{w, HSTRING, PCWSTR},
|
||||
Win32::{
|
||||
Foundation::{ERROR_FILE_NOT_FOUND, HWND},
|
||||
System::Com::CoInitialize,
|
||||
UI::{
|
||||
Shell::{ILCreateFromPathW, ILFree, SHOpenFolderAndSelectItems, ShellExecuteW},
|
||||
WindowsAndMessaging::SW_SHOW,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
pub fn show_item_in_directory(file: PathBuf) -> crate::Result<()> {
|
||||
let _ = unsafe { CoInitialize(None) };
|
||||
|
||||
let dir = file
|
||||
.parent()
|
||||
.ok_or_else(|| crate::Error::NoParent(file.clone()))?;
|
||||
|
||||
let dir = OsString::from(dir);
|
||||
let dir = HSTRING::from(dir);
|
||||
let dir_item = unsafe { ILCreateFromPathW(PCWSTR::from_raw(dir.as_ptr())) };
|
||||
|
||||
let file = OsString::from(file);
|
||||
let file = HSTRING::from(file);
|
||||
let file_item = unsafe { ILCreateFromPathW(PCWSTR::from_raw(file.as_ptr())) };
|
||||
|
||||
unsafe {
|
||||
if let Err(e) = SHOpenFolderAndSelectItems(dir_item, Some(&[file_item]), 0) {
|
||||
if e.code().0 == ERROR_FILE_NOT_FOUND.0 as i32 {
|
||||
ShellExecuteW(
|
||||
HWND::default(),
|
||||
w!("open"),
|
||||
PCWSTR::from_raw(dir.as_ptr()),
|
||||
PCWSTR::null(),
|
||||
PCWSTR::null(),
|
||||
SW_SHOW,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe {
|
||||
ILFree(Some(dir_item));
|
||||
ILFree(Some(file_item));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user