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,34 +158,44 @@ 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),
|
||||
};
|
||||
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,
|
||||
};
|
||||
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};
|
||||
|
||||
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()
|
||||
} else {
|
||||
Vec::new()
|
||||
// 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 = 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 {
|
||||
default,
|
||||
|
||||
Reference in New Issue
Block a user