0x00 写在前面的话
上节课了解了使用Rust才操作注册表的一些常用方法,这节课我们就用这些方法来实现“Windows11自定义任务栏位置”这个小工具。
0x01 &str转LPCWSTR
上节介绍的方法中,所有参数都存在的一个LPCWSTR
类型的参数。我们看源码可知,LPWSTR
类型其实就是WCHAR
类型的指针。WCHAR
又是wchar_t
类型,再继续看发现wchar_t
原来就是一个无符号16位整数了。(下面内容截取自源码)
pub type LPCWSTR = *const WCHAR; pub type WCHAR = wchar_t; pub type wchar_t = u16;
其实这也是winapi
里面带W
方法所常用的Unicode
编码类型了。那我们如何将&str
类型转为所需的LPCWSTR
类型呢。这就需要借助Rust提供的OsStr
类型了。转换代码如下:
unsafe fn str_to_lpcwstr(str: &str) -> Vec<u16> { let result: Vec<u16> = OsStr::new(str).encode_wide().chain(once(0)).collect(); return result; }
0x02 封装注册表操作方法
为了便于操作注册表,在这里对相应的方法简单封装下。
打开注册表
/// 打开注册表 /// [`main_hkey`] 是一个HKEY值,默认接收[`HKEY_CURRENT_USER`]等值 /// [`sub_key`] HKEY的子健 /// # Examples /// Basic usage: /// ``` /// let sub_key = "Software\\360\\333"; /// let hkey_result = reg_util::reg_open(HKEY_CURRENT_USER, sub_key); /// ``` pub(crate) fn reg_open(main_hkey: HKEY, sub_key: &str) -> Result<HKEY, String> { unsafe { let mut hkey: HKEY = null_mut(); let status = RegOpenKeyW(main_hkey, str_to_lpcwstr(sub_key).as_ptr(), &mut hkey); if status == SEC_E_OK { return Result::Ok(hkey); } return Result::Err(format!("status == {}", status)); } }
查询REG_BINARY的值
/// 查询注册表的REG_BINARY的值 pub(crate) fn reg_query_binary(hkey: &HKEY, key_name: &str) -> Vec<u8> { unsafe { let mut dword: DWORD = 0; let mut dtype: DWORD = 0; //查询 let status = RegQueryValueExW(*hkey, str_to_lpcwstr(key_name).as_ptr(), null_mut(), &mut dtype, null_mut(), &mut dword); let mut data_binary: Vec<u8> = vec![0; dword as usize]; if status == SEC_E_OK { // 存在值 RegQueryValueExW(*hkey, str_to_lpcwstr(key_name).as_ptr(), null_mut(), &mut dtype, data_binary.as_mut_ptr(), &mut dword); } return data_binary; }
保存REG_SZ类型的数据
/// 保存REG_SZ类型的数据 pub(crate) fn reg_save_binary(hkey: &HKEY, key_name: &str, value: &mut Vec<u8>) -> LSTATUS { unsafe { let status = RegSetValueExW(*hkey, str_to_lpcwstr(key_name).as_ptr(), 0, REG_BINARY, value.as_mut_ptr(), value.len() as u32); return status; } }
0x03 开始编写小工具
打开注册表
首先,我们先打开相应的注册表。
const SUB_KEY: &str = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StuckRects3"; // 打开注册表 let hkey_result = reg_util::reg_open(HKEY_CURRENT_USER, SUB_KEY);
如果打开成功。我们再去查询当前的值。
查询注册表
我们即将查找的注册表是二进制值,判断第12个数据,如果是0x00 则表示左,0x01 则表示上,0x02 则表示右,0x03 则表示下。
let mut reg_value = reg_util::reg_query_binary(&hkey, ITEM_KEY); let position_option = reg_value.get(12); match position_option { Some(LEFT) => { println!("【当前任务栏的位置在屏幕左侧!】"); } Some(RIGHT) => { println!("【当前任务栏的位置在屏幕右侧!】"); } Some(UP) => { println!("【当前任务栏的位置在屏幕上方!】"); } Some(DOWN) => { println!("【当前任务栏的位置在屏幕下方!】"); } Some(_) => { println!("【读取任务栏的位置失败!UNKNOWN】"); return; } None => { println!("【读取任务栏的位置失败!NONE】"); return; } }
修改注册表
我们接收键盘输入的数字,来修改注册表的值。这里仅接收0,1,2,3四个值。
let position = input_task_bar_position(); if position > 3 { println!("输入错误!"); return; } // 正确输入,构建二进制值 reg_value[12] = position; // 保存注册表 let status = reg_util::reg_save_binary(&hkey, ITEM_KEY, &mut reg_value); if status == SEC_E_OK { println!("修改成功!正在重启资源管理器......"); reboot_explorer(); println!("重启资源管理器成功!"); exit(0); } else { println!("修改失败!"); }
0x04 小结
至此,整个小工具就结束了。其实这里仅仅借此小工具来练习下使用Rust操作注册表。其实只要掌握如何使用Rust操作注册表的基本技巧,你们windows注册表的各种设置都不在话下了。