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

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

作者: L我是小学生 | 来源:发表于2021-10-11 20:03 被阅读0次

    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<u16> = 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<u16> = 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<u16> = OsStr::new("Software\\360\\333").encode_wide().chain(once(0)).collect();
    let mut val: Vec<u16> = 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<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);
        }
    
    RegOpenKeyW

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

    let mut hkey: HKEY = null_mut();
    let mut lp: Vec<u16> = 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任务栏位置(上)

          本文链接:https://www.haomeiwen.com/subject/ynhroltx.html