The following code may be helpful for you.
[package]
name = "folder_api_sample"
version = "0.1.0"
authors = ["benki"]
edition = "2021"
[dependencies.windows]
version = "0.43"
features = [
"Win32_Foundation",
"Win32_System_Com",
"Win32_System_Ole",
"Win32_UI_Shell",
]
use std::mem::ManuallyDrop;
use windows::{
core::{Interface, Result, BSTR, GUID},
w,
Win32::{
System::Com::{
CoCreateInstance, CoInitialize, CoUninitialize, CLSCTX_SERVER, VARIANT, VT_BSTR,
VT_DISPATCH,
},
UI::Shell::IShellDispatch,
},
};
// shldisp.h
const CLSID_SHELL: GUID = GUID {
data1: 0x13709620,
data2: 0xC279,
data3: 0x11CE,
data4: [0xA4, 0x9E, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00],
};
struct Com;
impl Drop for Com {
fn drop(&mut self) {
unsafe { CoUninitialize() };
}
}
struct Variant(VARIANT);
impl Drop for Variant {
fn drop(&mut self) {
unsafe {
match self.0.Anonymous.Anonymous.vt {
VT_BSTR => {
ManuallyDrop::drop(&mut ((*self.0.Anonymous.Anonymous).Anonymous.bstrVal))
}
VT_DISPATCH => {
ManuallyDrop::drop(&mut ((*self.0.Anonymous.Anonymous).Anonymous.pdispVal))
}
_ => (),
}
ManuallyDrop::drop(&mut self.0.Anonymous.Anonymous);
}
}
}
fn main() -> Result<()> {
unsafe {
CoInitialize(None)?;
let _com = Com;
let shell: IShellDispatch = CoCreateInstance(&CLSID_SHELL, None, CLSCTX_SERVER)?;
let mut dir = VARIANT::default();
(*dir.Anonymous.Anonymous).vt = VT_BSTR;
(*dir.Anonymous.Anonymous).Anonymous.bstrVal = ManuallyDrop::new(r"C:\path\to\dir".into());
let dir = Variant(dir);
let folder = shell.NameSpace(&dir.0)?;
let name = BSTR::from_wide(w!("file_name.mov").as_wide());
let folder_item = folder.ParseName(&name)?;
let mut item = VARIANT::default();
(*item.Anonymous.Anonymous).vt = VT_DISPATCH;
(*item.Anonymous.Anonymous).Anonymous.pdispVal =
ManuallyDrop::new(Some(folder_item.cast()?));
let item = Variant(item);
let details = folder.GetDetailsOf(&item.0, 208)?;
println!("{details}");
}
Ok(())
}