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

如何监听Windows注册表键值的变化?

跟踪Windows注册表键值变化的Rust工具方案

1. 原生Windows API封装实现

直接调用Windows系统的RegNotifyChangeKeyValue API是最可靠的方式,这是系统原生的注册表变更通知机制,你可以通过winapi或windows crate结合现有代码实现:

use std::sync::mpsc;
use std::thread;
use windows::Win32::System::Registry::{RegNotifyChangeKeyValue, REG_NOTIFY_CHANGE_LAST_SET};
use windows_registry::{CURRENT_USER, RegKey};

pub fn watch_light_theme_change() {
    let (sender, receiver) = mpsc::channel();

    thread::spawn(move || {
        let key = CURRENT_USER
            .open(r#"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"#)
            .expect("Failed to open registry key");
        
        // 获取原生注册表句柄
        let hkey = key.raw_handle();

        loop {
            // 阻塞等待变更通知
            unsafe {
                RegNotifyChangeKeyValue(
                    hkey,
                    false,
                    REG_NOTIFY_CHANGE_LAST_SET,
                    None,
                    true,
                ).expect("Failed to register registry watch");
            }

            // 发送变更信号到主线程
            sender.send(()).expect("Failed to send change signal");
        }
    });

    // 主线程监听并处理变更
    for _ in receiver {
        let is_light = is_light_theme();
        println!("Theme changed: {}", if is_light { "Light" } else { "Dark" });
    }
}

// 你的原有注册表读取函数
pub fn is_light_theme() -> bool {
    let val = CURRENT_USER
        .open(r#"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"#)
        .expect("Failed to get registry key")
        .get_u32("AppsUseLightTheme")
        .expect("Failed to get registry value");
    println!("{}", val);
    val != 0
}

2. 第三方封装库替代

如果不想直接写Win32 API调用,可以用registry-watch crate,它封装了RegNotifyChangeKeyValue,用法更简洁:

use registry_watch::RegistryWatcher;
use windows_registry::CURRENT_USER;

pub fn setup_theme_watcher() {
    let path = r#"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"#;
    let mut watcher = RegistryWatcher::new(CURRENT_USER, path).expect("Failed to create watcher");

    watcher.watch("AppsUseLightTheme", |_old_val, new_val| {
        let is_light = new_val.as_u32().unwrap_or(0) != 0;
        println!("Theme changed to: {}", if is_light { "Light" } else { "Dark" });
    }).expect("Failed to watch registry value");

    // 阻塞主线程维持监听
    watcher.run();
}

关键注意点

  • 原生API的通知是单次触发的,所以需要循环重新注册监听(registry-watch内部已处理循环逻辑)。
  • 访问CURRENT_USER路径下的注册表键无需管理员权限,若监听系统级键则需要提升权限。
  • 若需要监听多个键或值,registry-watch支持批量添加监听任务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 01:53:18