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