use crate::utils::{Println, run_commands};
use lazy_static::lazy_static;
use std::collections::HashMap;
use std::error::Error;
use winreg::enums::{HKEY_LOCAL_MACHINE, REG_SZ};
use winreg::{RegKey, RegValue};
lazy_static! {
static ref RegistryCommonFolders:HashMap<String, String> = {
let mycomputer = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace\{%s}";
let folderdescriptions = r"SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\{%s}\PropertyBag";
let mut sub_key: HashMap<String, String> = HashMap::new();
sub_key.insert("3D_OBJECTS".to_string(),mycomputer.replace("%s","0DB7E03F-FC29-4DC6-9020-FF41B59E513A"));
[
("PICTURES","0ddd015d-b06c-45d5-8c4c-f59713854639"), ("VIDEOS","35286a68-3c57-41a1-bbb1-0eae73d76c95"), ("DOWNLOADS","7d83ee9b-2244-4e70-b1f5-5393042af1e4"), ("MUSIC","a0c69a99-21c8-4671-8703-7934162fcf1d"), ("DESKTOP","B4BFCC3A-DB2C-424C-B029-7FE99A87C641"), ("DOCUMENTS","f42ee2d3-909f-4907-8871-4c22fc0bf756") ].iter().for_each(|(k,v)| {
sub_key.insert(k.to_string(), folderdescriptions.replace("%s",v));
});
sub_key
};
}
fn get_3d_objects() -> Result<bool, Box<dyn Error>> {
let hk = RegKey::predef(HKEY_LOCAL_MACHINE);
let key = RegistryCommonFolders
.get("3D_OBJECTS")
.expect("failed to get 3D_OBJECTS");
Ok(hk.open_subkey(key).is_ok())
}
pub fn get_common_folder_state<T: AsRef<str>>(key: T) -> Result<bool, Box<dyn Error>> {
let key = key.as_ref();
if key == "3D_OBJECTS" {
return get_3d_objects();
}
let path = RegistryCommonFolders
.get(key)
.expect(format!("No Folder for key {}", key).as_str());
let reg_key = RegKey::predef(HKEY_LOCAL_MACHINE).open_subkey(path);
if reg_key.is_err() {
return Err(format!("open_subkey 错误 {} {}", key, path).into());
}
let raw_value = reg_key.unwrap().get_raw_value("ThisPCPolicy");
if raw_value.is_err() {
println!("get_raw_value 错误 {} {}", key, path);
return Ok(false);
}
let value = &raw_value.unwrap();
if value.vtype == REG_SZ {
let res = value.to_string();
return if res == "Show" {
Ok(true)
} else if res == "Hide" {
Ok(false)
} else {
Err(format!("emme 这个值两个都没匹配到 {} {}", key, res).into())
};
}
Err(format!("值类型错误 !=RegType::REG_SZ {} {:?}", key, value.vtype).into())
}
pub fn switch_by_api(key: &str, show: bool) -> Result<(), Box<dyn Error>> {
let path = RegistryCommonFolders
.get(key)
.expect(format!("No Folder for key {}", key).as_str());
let bytes = (if show { "Show" } else { "Hide" }).as_bytes().to_vec();
match RegKey::predef(HKEY_LOCAL_MACHINE).open_subkey(path) {
Ok(reg_key) => {
match reg_key.set_raw_value(
"ThisPCPolicy",
&RegValue {
vtype: REG_SZ,
bytes: bytes.into(),
},
) {
Ok(_) => Ok(()),
Err(e) => Err(e.to_string().into()),
}
}
Err(e) => Err(format!("open_subkey 错误 {} {} {}", key, path, e).into()),
}
}
fn switch_by_cmd(key: &str, show: bool) {
let bytes = if !show { "Show" } else { "Hide" };
let path = RegistryCommonFolders
.get(key)
.expect(format!("No Folder for key {}", key).as_str());
if key == "3D_OBJECTS" {
let hk = RegKey::predef(HKEY_LOCAL_MACHINE);
if show {
match hk.delete_subkey(path) {
Ok(_) => {}
Err(e) => {
println!("delete_subkey Error: {}", e)
}
};
} else {
match hk.create_subkey(path) {
Ok(_) => {}
Err(e) => {
println!("create_subkey Error: {}", e)
}
};
}
} else {
run_commands(
format!(
"reg add \"HKLM\\{}\" /v ThisPCPolicy /t REG_SZ /d \"{}\" /f",
path, bytes
),
true,
false,
)
.print_ln();
}
}
pub fn show<T: AsRef<str>>(key: T) {
switch_by_cmd(key.as_ref(), true)
}
pub fn hide<T: AsRef<str>>(key: T) {
switch_by_cmd(key.as_ref(), false)
}
pub fn get_all_state() -> HashMap<String, bool> {
let mut hm: HashMap<String, bool> = HashMap::new();
RegistryCommonFolders
.keys()
.for_each(|f| match get_common_folder_state(f) {
Ok(state) => {
hm.insert(f.to_string(), state);
}
Err(e) => println!("{}", e),
});
hm
}