write shit
This commit is contained in:
178
Cargo.lock
generated
178
Cargo.lock
generated
@ -61,6 +61,12 @@ dependencies = [
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.0"
|
||||
@ -119,6 +125,59 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
|
||||
[[package]]
|
||||
name = "comfy-table"
|
||||
version = "7.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b03b7db8e0b4b2fdad6c551e634134e99ec000e5c8c3b6856c65e8bbaded7a3b"
|
||||
dependencies = [
|
||||
"crossterm",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm"
|
||||
version = "0.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d8b9f2e4c67f833b660cdb0a3523065869fb35570177239812ed4c905aeff87b"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossterm_winapi",
|
||||
"document-features",
|
||||
"parking_lot",
|
||||
"rustix",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossterm_winapi"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "document-features"
|
||||
version = "0.2.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
|
||||
dependencies = [
|
||||
"litrs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
@ -141,6 +200,33 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.176"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
||||
|
||||
[[package]]
|
||||
name = "litrs"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.28"
|
||||
@ -165,6 +251,29 @@ version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.101"
|
||||
@ -183,6 +292,15 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.3"
|
||||
@ -212,12 +330,37 @@ version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
@ -261,6 +404,18 @@ version = "1.0.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-segmentation"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-width"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
@ -360,10 +515,33 @@ name = "wfassoc_exec"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"comfy-table",
|
||||
"thiserror",
|
||||
"wfassoc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.0"
|
||||
|
@ -1,6 +1,9 @@
|
||||
//! This crate provide utilities fetching and manilupating Windows file association.
|
||||
//! All code under crate are following Microsoft document: https://learn.microsoft.com/en-us/windows/win32/shell/customizing-file-types-bumper
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
compile_error!("Crate wfassoc is only supported on Windows.");
|
||||
|
||||
use regex::Regex;
|
||||
use std::fmt::Display;
|
||||
use std::path::PathBuf;
|
||||
@ -8,9 +11,6 @@ use std::str::FromStr;
|
||||
use std::sync::LazyLock;
|
||||
use thiserror::Error as TeError;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
compile_error!("Crate wfassoc is only supported on Windows.");
|
||||
|
||||
// region: Error Types
|
||||
|
||||
/// All possible error occurs in this crate.
|
||||
@ -29,6 +29,7 @@ pub enum Error {
|
||||
// endregion
|
||||
|
||||
/// The scope where wfassoc will operate.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum Scope {
|
||||
/// Scope for current user.
|
||||
User,
|
||||
@ -40,17 +41,17 @@ pub enum Scope {
|
||||
///
|
||||
/// It usually means that checking whether current process is running as Administrator.
|
||||
/// Return true if it is, otherwise false.
|
||||
///
|
||||
///
|
||||
/// Reference: https://learn.microsoft.com/en-us/windows/win32/api/securitybaseapi/nf-securitybaseapi-checktokenmembership
|
||||
pub fn has_privilege() -> bool {
|
||||
use windows_sys::core::BOOL;
|
||||
use windows_sys::Win32::Foundation::HANDLE;
|
||||
use windows_sys::Win32::Security::{
|
||||
SECURITY_NT_AUTHORITY, PSID, AllocateAndInitializeSid, CheckTokenMembership, FreeSid
|
||||
AllocateAndInitializeSid, CheckTokenMembership, FreeSid, PSID, SECURITY_NT_AUTHORITY,
|
||||
};
|
||||
use windows_sys::Win32::System::SystemServices:: {
|
||||
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS
|
||||
use windows_sys::Win32::System::SystemServices::{
|
||||
DOMAIN_ALIAS_RID_ADMINS, SECURITY_BUILTIN_DOMAIN_RID,
|
||||
};
|
||||
use windows_sys::core::BOOL;
|
||||
|
||||
let nt_authority = SECURITY_NT_AUTHORITY.clone();
|
||||
let mut administrators_group: PSID = PSID::default();
|
||||
@ -75,13 +76,8 @@ pub fn has_privilege() -> bool {
|
||||
}
|
||||
|
||||
let mut is_member: BOOL = BOOL::default();
|
||||
let success: BOOL = unsafe {
|
||||
CheckTokenMembership(
|
||||
HANDLE::default(),
|
||||
administrators_group,
|
||||
&mut is_member,
|
||||
)
|
||||
};
|
||||
let success: BOOL =
|
||||
unsafe { CheckTokenMembership(HANDLE::default(), administrators_group, &mut is_member) };
|
||||
|
||||
unsafe {
|
||||
FreeSid(administrators_group);
|
||||
@ -90,7 +86,7 @@ pub fn has_privilege() -> bool {
|
||||
if success == 0 {
|
||||
panic!("Win32 CheckTokenMembership() failed");
|
||||
}
|
||||
|
||||
|
||||
is_member != 0
|
||||
}
|
||||
|
||||
@ -113,6 +109,10 @@ impl FileExt {
|
||||
None => Err(ParseFileExtError::new()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn query(&self, scope: Scope) -> Option<FileExtAssoc> {
|
||||
FileExtAssoc::new(self, scope)
|
||||
}
|
||||
}
|
||||
|
||||
/// The error occurs when try parsing string into FileExt.
|
||||
@ -140,6 +140,55 @@ impl FromStr for FileExt {
|
||||
}
|
||||
}
|
||||
|
||||
/// The association infomations of specific file extension.
|
||||
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,
|
||||
};
|
||||
|
||||
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()
|
||||
};
|
||||
|
||||
Some(Self {
|
||||
default,
|
||||
open_with_progids,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_default(&self) -> &str {
|
||||
&self.default
|
||||
}
|
||||
|
||||
pub fn len_open_with_progid(&self) -> usize {
|
||||
self.open_with_progids.len()
|
||||
}
|
||||
|
||||
pub fn iter_open_with_progids(&self) -> impl Iterator<Item = &str> {
|
||||
self.open_with_progids.iter().map(|s| s.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
// endregion
|
||||
|
||||
// region: Executable Resource
|
||||
|
@ -10,3 +10,4 @@ license = "SPDX:MIT"
|
||||
thiserror = { workspace = true }
|
||||
wfassoc = { path="../wfassoc" }
|
||||
clap = { version="4.5.48", features=["derive"]}
|
||||
comfy-table = "7.2.1"
|
||||
|
@ -1,7 +1,8 @@
|
||||
use clap::{Parser, Subcommand};
|
||||
use comfy_table::Table;
|
||||
use std::process;
|
||||
use wfassoc::{Error as WfError};
|
||||
use thiserror::Error as TeError;
|
||||
use wfassoc::{Error as WfError, FileExt, Scope};
|
||||
|
||||
// region: Basic Types
|
||||
|
||||
@ -10,7 +11,7 @@ use thiserror::Error as TeError;
|
||||
enum Error {
|
||||
/// Error from wfassoc core.
|
||||
#[error("{0}")]
|
||||
Core(#[from] WfError)
|
||||
Core(#[from] WfError),
|
||||
}
|
||||
|
||||
/// Result type used in this executable.
|
||||
@ -89,9 +90,40 @@ fn run_unregister(cli: Cli) -> Result<()> {
|
||||
}
|
||||
|
||||
fn run_query(cli: Cli) -> Result<()> {
|
||||
let exts = [
|
||||
".jpg", ".jfif", ".gif", ".bmp", ".png", ".ico", ".jpeg", ".tif", ".tiff", ".webp", ".svg",
|
||||
".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(), "", ""]);
|
||||
}
|
||||
}
|
||||
|
||||
println!("{table}");
|
||||
|
||||
// let program = Program::new();
|
||||
// program.query()?;
|
||||
println!("Has privilege: {}", wfassoc::has_privilege());
|
||||
//println!("Has privilege: {}", wfassoc::has_privilege());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user