write shit
This commit is contained in:
@ -28,7 +28,9 @@ pub enum Error {
|
||||
|
||||
// endregion
|
||||
|
||||
/// The scope where wfassoc will operate.
|
||||
// region: Basic Types
|
||||
|
||||
/// The scope where wfassoc will register and unregister.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Scope {
|
||||
/// Scope for current user.
|
||||
@ -37,6 +39,18 @@ pub enum Scope {
|
||||
System,
|
||||
}
|
||||
|
||||
/// The view when wfassoc querying infomations.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum View {
|
||||
/// The view of current user.
|
||||
User,
|
||||
/// The view of system.
|
||||
System,
|
||||
/// Hybrid view of User and System.
|
||||
/// It can be seen as that we use System first and then use User to override any existing items.
|
||||
Hybrid,
|
||||
}
|
||||
|
||||
/// Check whether current process has administrative privilege.
|
||||
///
|
||||
/// It usually means that checking whether current process is running as Administrator.
|
||||
@ -90,10 +104,13 @@ pub fn has_privilege() -> bool {
|
||||
is_member != 0
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region: File Extension
|
||||
|
||||
/// The struct representing an file extension which must start with dot (`.`)
|
||||
/// and followed by at least one arbitrary characters.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct FileExt {
|
||||
/// The body of file extension (excluding dot).
|
||||
inner: String,
|
||||
@ -110,14 +127,14 @@ impl FileExt {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn query(&self, scope: Scope) -> Option<FileExtAssoc> {
|
||||
FileExtAssoc::new(self, scope)
|
||||
pub fn query(&self, view: View) -> Option<FileExtAssoc> {
|
||||
FileExtAssoc::new(self, view)
|
||||
}
|
||||
}
|
||||
|
||||
/// The error occurs when try parsing string into FileExt.
|
||||
#[derive(Debug, TeError)]
|
||||
#[error("given file extension name is illegal")]
|
||||
#[error("given file extension is illegal")]
|
||||
pub struct ParseFileExtError {}
|
||||
|
||||
impl ParseFileExtError {
|
||||
@ -141,31 +158,41 @@ impl FromStr for FileExt {
|
||||
}
|
||||
|
||||
/// The association infomations of specific file extension.
|
||||
#[derive(Debug)]
|
||||
pub struct FileExtAssoc {
|
||||
default: String,
|
||||
open_with_progids: Vec<String>,
|
||||
}
|
||||
|
||||
impl FileExtAssoc {
|
||||
fn new(file_ext: &FileExt, scope: Scope) -> Option<Self> {
|
||||
let hk = match scope {
|
||||
Scope::User => winreg::RegKey::predef(winreg::enums::HKEY_CURRENT_USER),
|
||||
Scope::System => winreg::RegKey::predef(winreg::enums::HKEY_LOCAL_MACHINE),
|
||||
fn new(file_ext: &FileExt, view: View) -> Option<Self> {
|
||||
use winreg::RegKey;
|
||||
use winreg::enums::{HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, KEY_READ};
|
||||
|
||||
// navigate to extension container
|
||||
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 = hk
|
||||
.open_subkey_with_flags("Software\\Classes", winreg::enums::KEY_READ)
|
||||
.unwrap();
|
||||
let thisext =
|
||||
match classes.open_subkey_with_flags(file_ext.to_string(), winreg::enums::KEY_READ) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return None,
|
||||
let classes = match view {
|
||||
View::User | View::System => hk
|
||||
.open_subkey_with_flags("Software\\Classes", KEY_READ)
|
||||
.unwrap(),
|
||||
View::Hybrid => hk.open_subkey_with_flags("", KEY_READ).unwrap(),
|
||||
};
|
||||
|
||||
// open extension key if possible
|
||||
let thisext = match classes.open_subkey_with_flags(file_ext.to_string(), KEY_READ) {
|
||||
Ok(v) => v,
|
||||
Err(_) => return None,
|
||||
};
|
||||
|
||||
// fetch extension infos.
|
||||
let default = thisext.get_value("").unwrap_or(String::new());
|
||||
let open_with_progids = if let Ok(progids) =
|
||||
thisext.open_subkey_with_flags("OpenWithProdIds", winreg::enums::KEY_READ)
|
||||
{
|
||||
progids.enum_keys().map(|x| x.unwrap()).collect()
|
||||
let open_with_progids =
|
||||
if let Ok(progids) = thisext.open_subkey_with_flags("OpenWithProdIds", KEY_READ) {
|
||||
progids.enum_keys().map(|x| x.unwrap()).filter(|k| !k.is_empty()).collect()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
@ -2,7 +2,7 @@ use clap::{Parser, Subcommand};
|
||||
use comfy_table::Table;
|
||||
use std::process;
|
||||
use thiserror::Error as TeError;
|
||||
use wfassoc::{Error as WfError, FileExt, Scope};
|
||||
use wfassoc::{Error as WfError, FileExt, Scope, View};
|
||||
|
||||
// region: Basic Types
|
||||
|
||||
@ -95,31 +95,36 @@ fn run_query(cli: Cli) -> Result<()> {
|
||||
".kra", ".xcf", ".avif", ".qoi", ".apng", ".exr",
|
||||
];
|
||||
|
||||
let mut table = Table::new();
|
||||
table.set_header(["Extension", "Default Open", "Open With"]);
|
||||
for ext in exts.iter().map(|e| FileExt::new(e).unwrap()) {
|
||||
if let Some(ext_assoc) = ext.query(Scope::User) {
|
||||
if ext_assoc.len_open_with_progid() == 0 {
|
||||
table.add_row([ext.to_string().as_str(), ext_assoc.get_default(), ""]);
|
||||
} else {
|
||||
for (i, open_with_entry) in ext_assoc.iter_open_with_progids().enumerate() {
|
||||
if i == 0 {
|
||||
table.add_row([
|
||||
ext.to_string().as_str(),
|
||||
ext_assoc.get_default(),
|
||||
open_with_entry,
|
||||
]);
|
||||
} else {
|
||||
table.add_row(["", "", open_with_entry]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
table.add_row([ext.to_string().as_str(), "", ""]);
|
||||
if let Some(ext_assoc) = ext.query(View::Hybrid) {
|
||||
println!("{:?}", ext_assoc)
|
||||
}
|
||||
}
|
||||
|
||||
println!("{table}");
|
||||
// let mut table = Table::new();
|
||||
// table.set_header(["Extension", "Default Open", "Open With"]);
|
||||
// for ext in exts.iter().map(|e| FileExt::new(e).unwrap()) {
|
||||
// if let Some(ext_assoc) = ext.query(View::Hybrid) {
|
||||
// if ext_assoc.len_open_with_progid() == 0 {
|
||||
// table.add_row([ext.to_string().as_str(), ext_assoc.get_default(), ""]);
|
||||
// } else {
|
||||
// for (i, open_with_entry) in ext_assoc.iter_open_with_progids().enumerate() {
|
||||
// if i == 0 {
|
||||
// table.add_row([
|
||||
// ext.to_string().as_str(),
|
||||
// ext_assoc.get_default(),
|
||||
// open_with_entry,
|
||||
// ]);
|
||||
// } else {
|
||||
// table.add_row(["", "", open_with_entry]);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// table.add_row([ext.to_string().as_str(), "", ""]);
|
||||
// }
|
||||
// }
|
||||
// println!("{table}");
|
||||
|
||||
// let program = Program::new();
|
||||
// program.query()?;
|
||||
|
Reference in New Issue
Block a user