1
0

feat(wfassoc): add query_ext method and improve CLI output

- Implement query_ext method to check default program associations
- Enhance CLI query command with tabular output showing associations
- Refactor program building into Composition struct for better organization
- Update documentation comments for clarity
This commit is contained in:
2025-10-19 15:12:15 +08:00
parent d5fed1e580
commit f42c50ce10
4 changed files with 129 additions and 36 deletions

View File

@@ -98,8 +98,8 @@ impl From<&str> for ProgId {
impl Display for ProgId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
ProgId::Other(v) => v.fmt(f),
ProgId::Std(v) => v.fmt(f),
ProgId::Other(v) => write!(f, "{}", v),
ProgId::Std(v) => write!(f, "{}", v),
}
}
}

View File

@@ -9,6 +9,7 @@ pub mod utilities;
pub mod wincmd;
pub mod winreg_extra;
use assoc::{Ext, ProgId};
use indexmap::{IndexMap, IndexSet};
use regex::Regex;
use std::ffi::OsStr;
@@ -19,7 +20,6 @@ use winreg::RegKey;
use winreg::enums::{
HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, KEY_READ, KEY_WRITE,
};
use assoc::{Ext, ProgId};
// region: Error Types
@@ -327,7 +327,7 @@ impl Program {
impl Program {
const CLASSES: &str = "Software\\Classes";
/// Set the default "open with" of given extension to this program.
/// Set the default "open with" of given token associated extension to this program.
pub fn link_ext(&self, ext: Token, scope: Scope) -> Result<()> {
// Check privilege
if !scope.has_privilege() {
@@ -357,10 +357,10 @@ impl Program {
Ok(())
}
/// Remove this program from the default "open with" of given extension.
/// Remove this program from the default "open with" of given token associated extension.
///
/// If the default "open with" of given extension is not our program,
/// this function do nothing.
/// or there is no such file extension, this function do nothing.
pub fn unlink_ext(&self, ext: Token, scope: Scope) -> Result<()> {
// Check privilege
if !scope.has_privilege() {
@@ -398,6 +398,44 @@ impl Program {
// Okey
Ok(())
}
/// Query the default "open with" of given token associated extension.
///
/// This function will return its associated ProgId if it is existing.
pub fn query_ext(&self, ext: Token, view: View) -> Result<Option<ProgId>> {
// Fetch file extension
let (ext, _) = match self.exts.get_index(ext) {
Some(v) => v,
None => return Err(Error::InvalidExtToken),
};
// Fetch root key and navigate to Classes
let hk = match view {
View::User => RegKey::predef(HKEY_CURRENT_USER),
View::System => RegKey::predef(HKEY_LOCAL_MACHINE),
View::Hybrid => RegKey::predef(HKEY_CLASSES_ROOT),
};
let classes = match view {
View::User | View::System => hk.open_subkey_with_flags(Self::CLASSES, KEY_READ)?,
View::Hybrid => hk.open_subkey_with_flags("", KEY_READ)?,
};
// Open key for this extension if possible
let rv =
match winreg_extra::try_open_subkey_with_flags(&classes, ext.to_string(), KEY_READ)? {
Some(subkey) => {
// Try get associated ProgId if possible
match winreg_extra::try_get_value::<String, _>(&subkey, "")? {
Some(value) => Some(ProgId::from(value.as_str())),
None => None,
}
}
None => None,
};
// Okey
Ok(rv)
}
}
impl Program {
@@ -429,7 +467,7 @@ impl Program {
ProgId::Std(assoc::StdProgId::new(
&self.identifier,
&utilities::capitalize_first_ascii(ext.inner()),
None
None,
))
}
}