Rust实战——注册表之自定义Windows11任务栏位置(下)

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;
}

具体原理可以参见这篇来自知乎的文章“https://zhuanlan.zhihu.com/p/367190469”。这篇文章介绍的比较详细了,我在这里就不再赘述了。

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注册表的各种设置都不在话下了。

0x05 源码

关注公众号:《Rust学习日记》回复:【win11注册表】获取源码。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uuuhhhyyy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值