You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用windows crate调用Windows API读取注册表键时出现参数错误

解决Rust调用Windows API读取注册表时的0x80070057参数错误

你遇到的0x80070057(参数不正确)错误,直接原因是第二次调用RegGetValueW时违反了Windows API的参数规则:当传入数据缓冲区(lpData参数)时,必须同时传入缓冲区的大小指针(lpcbData参数),API需要通过这个参数确认缓冲区容量,否则会返回参数错误。

你的代码中第二次调用RegGetValueW时最后一个参数传的是None,这就是问题的核心。

修正后的代码

use std::alloc::{alloc, dealloc, Layout};
use windows::Win32::System::Registry::{RegGetValueW, HKEY, REG_ROUTINE_FLAGS};
use windows::core::{HSTRING, PCWSTR, Error};
use std::os::raw::c_void;

pub fn get_registry_key<'a>(hkey: HKEY, subkey: &'a str, key: &'a str, flags: REG_ROUTINE_FLAGS) -> Result<(*mut c_void, u32), Error> {
    unsafe {
        let mut data_length: u32 = 0;
        let subkey_hstring = HSTRING::from(subkey);
        let key_hstring = HSTRING::from(key);

        // 第一次调用获取数据长度
        RegGetValueW(
            hkey,
            PCWSTR(subkey_hstring.as_ptr()),
            PCWSTR(key_hstring.as_ptr()),
            flags,
            None,
            None,
            Some(&mut data_length),
        )?;
        println!("Length: {}", data_length);

        // 分配内存,使用4字节对齐适配多数注册表数据类型(如REG_DWORD、REG_SZ等)
        let layout = Layout::from_size_align(data_length as usize, 4).unwrap();
        let data = alloc(layout) as *mut c_void;

        // 第二次调用必须传入数据缓冲区和长度指针
        RegGetValueW(
            hkey,
            PCWSTR(subkey_hstring.as_ptr()),
            PCWSTR(key_hstring.as_ptr()),
            flags,
            None,
            Some(data),
            Some(&mut data_length), // 此处不能为None
        )?;

        // 返回数据指针和实际写入的长度,方便后续处理与内存释放
        Ok((data, data_length))
    }
}

// 使用示例(记得手动释放内存):
// fn main() -> Result<(), Error> {
//     let (data, len) = get_registry_key(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "ProductName", REG_ROUTINE_FLAGS(0))?;
//     // 处理数据...
//     unsafe { dealloc(data as *mut u8, Layout::from_size_align(len as usize, 4).unwrap()); }
//     Ok(())
// }

关键说明

  1. 参数约束:RegGetValueW明确规定,若lpData不为空,lpcbData必须指向一个DWORD变量,用于传入缓冲区大小并接收实际写入的数据长度。
  2. 内存对齐:将内存对齐值从1改为4,适配注册表常见数据类型的对齐要求,避免潜在的未定义行为。
  3. 内存安全:函数返回数据指针后,需要手动调用dealloc释放内存,否则会造成内存泄漏。

内容的提问来源于stack exchange,提问作者nrp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 23:25:55