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

0x00 说在前面的废话

2021年10月5日这一天注定是不寻常的一天......因为“巨硬”发布了Windows 11。本人在第一时间装了Windows 11。体验还算不错,下面是windows 11的开始菜单啦。感觉又要适应一段时间了。但是发现了一个问题,这货!任务栏不能改!位!置!这难不倒我吧,,上网查资料发现可以通过修改注册表来更改任务栏的位置。看到这里,要不咱们就用Rust来大干一场,正好练习下Rust的winapi。后来......就有了这篇文章。

本文也正好借此机会说下Rust使用winapi的一些坑。如果您是一直从事winapi开发的大佬,恳请大佬批评改正。本人对winapi也不是很熟悉,且Rust版的winapi也没有文档,只能通过C++的文档来写了,难免存在不足之处。

0x01 自定义windows11的任务栏位置

微软虽然没有提供修改任务栏位置的设置项,但是仍然可以通过修改注册表来达到改变任务栏的位置。操作注册表前建议备份注册表。打开注册表编辑器,定位到:\HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\StuckRects3,然后双击 Settings 打开。

在打开的二进制编辑器中,找到红框标注的 03(FE 下方的那个),将其修改为 00(左)、01(上)、02(右),接着使用软媒魔方重启 Windows 资源管理器,即可改变任务栏位置。

经过本人的亲测,任务栏在上下方式没有任何问题的,但是在左右两侧,会导致中间的图标显示不出来。下面是效果图。

0x02 操作注册表的常用方法

要操作Windows注册表一定需要winapi,本节课所使用的winapi库是0.3.9版本(截至写这篇文章时是最新的)。操作注册表无非就是增、删、改、查这四个方法啦。在winapi里面分别对应RegCreateKeyRegDeleteKeyRegSetValueRegQueryValue,最后再加上一个创建方法RegOpenKey

简单介绍下这几个常用的相关方法吧。

RegCreateKeyExW

该方法是用来创建一个项。这个方法有9个参数,不要被吓到。有很多参数默认就可以。第一个是HKEY类型,可以传微软默认的5个值之一。这里以HKEY_CURRENT_USER为例。第二个参数是创建的项的名称(该字段是LPCWSTR类型,后面会介绍如何构建这个类型),第三到第五个参数,以及第七个参数按照下方默认来写即可。第六个参数,是创建子键后的结果,是一个HKEY类型。

let mut hkey: HKEY = null_mut();
let mut lp: Vec = OsStr::new("Software\\360\\333").encode_wide().chain(once(0)).collect();
let create_result = RegCreateKeyExW(HKEY_CURRENT_USER,
                                    lp.as_ptr(),
                                    0,
                                    null_mut(),
                                    REG_OPTION_NON_VOLATILE,
                                    KEY_ALL_ACCESS,
                                    null_mut(),
                                    &mut hkey,
                                    null_mut());
RegDeleteKeyExW

该方法是用来删除一个项。请谨慎使用该方法,一旦删除,将不可逆转。这个方法有4个参数,第一个参数同RegCreateKeyExW方法的第一个参数。第二个参数是要删除项的名称。第三和第四按照以下代码默认即可。

let mut lp: Vec = OsStr::new("Software\\360\\333").encode_wide().chain(once(0)).collect();
let result = RegDeleteKeyExW(HKEY_CURRENT_USER, lp.as_ptr(), KEY_ALL_ACCESS, 0);
RegSetValueExW

该方法是用来修改一个键值。请谨慎使用该方法,一旦修改,将不可逆转。该方法有6个参数,第一个参数是HKEY类型的参数,通常传递RegOpenKey方法返回的参数。第二个参数是要修改值的键名。第三个参数默认0即可。第四个参数是你要修改值的类型,通常有REG_SZREG_BINARYREG_DWORDREG_DWORD_LITTLE_ENDIANREG_DWORD_BIG_ENDIAN等10多种类型。第五个参数就是要修改的值了。第六个参数则是新值的占内存的长度了。

let mut lp: Vec = OsStr::new("Software\\360\\333").encode_wide().chain(once(0)).collect();
let mut val: Vec = OsStr::new("ABCD").encode_wide().chain(once(0)).collect();
let result = RegSetValueExW(hkey, key.as_ptr(), 0, REG_SZ, val.as_ptr() as *const u8, (size_of_val(&val) as u32));
RegQueryValueExW

该方法是用来查询一个键的当前值内容。该方法也拥有6个参数。第一个参数是HKEY类型的参数,通常传递RegOpenKey方法返回的参数。第二个参数是要修改值的键名称。第三个参数模式为null_mut(),第四个参数是保存当前查询值的类型。第五个参数是保存当前值的数据内容。第六个参数是保存当前数据的长度。此方法需要调用两次。第一次是仅获取返回的数据长度,第二次调用时收集数据。因此第一次调用时,第五个参数可以为null_mut(),第二次调用时则是一个带有长度的数组了。

let mut dword: DWORD = 0;
let mut dtype: DWORD = 0;

//查询
let status = RegQueryValueExW(*hkey,
                              lp.as_ptr(),
                              null_mut(),
                              &mut dtype,
                              null_mut(),
                              &mut dword);

    let mut data_binary: Vec = 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);
    }
RegOpenKeyW

该方法用来打开一个注册表项。这个方法很简单,该方法有三个参数。第一个参数是HKEY类型的参数,第二个是子项的名称,第三个是打开后保存的HKEY结果

let mut hkey: HKEY = null_mut();
let mut lp: Vec = OsStr::new("Software\\360\\333").encode_wide().chain(once(0)).collect();
let status = RegOpenKeyW(HKEY_CURRENT_USER,
                                 lp.as_ptr(),
                                 &mut hkey);

0x03 小结

本节课简单介绍了下使用Rust来操作注册表常用的几个参数。其实跟C++大同小异,有一点儿要注意的是Windows的16字宽的编码,下节再讲解。另外我们离windows11注册表修改的工具还比较远,希望大家耐心读文章。

0x04 关于本文源码

完整的源码,我将在该文章全部结束后放出。如果有什么不明白的可以关注公众号:《Rust学习日记》给我留言。当然源码也会通过公众号给出哟~

你可能感兴趣的:(Rust实战——注册表之自定义Windows11任务栏位置(上))