desktop: read StartupApproved through the registry API, no reg.exe (the security test allows no other programs)

This commit is contained in:
CRTkafa 2026-10-25 21:11:31 +08:00
parent 53845c6dd9
commit d43c95db7e
4 changed files with 18 additions and 22 deletions

View file

@ -90,27 +90,20 @@ fn tray(app: &tauri::App) -> tauri::Result<()> {
}
/// A tray menu pick (a menu panel row or the native fallback menu): tray.rs maps the id to what it does.
/// Whether the person turned storebound off in Windows' Startup apps (Settings / Task Manager), from the `reg query`
/// output of HKCU\...\Explorer\StartupApproved\Run /v storebound: the first byte of the REG_BINARY is even when enabled
/// (02, 06), odd when disabled (03, 07). No entry: not turned off. Pure.
pub fn startup_approved_off(reg_query_out: &str) -> bool {
reg_query_out
.lines()
.find(|l| l.contains("REG_BINARY"))
.and_then(|l| l.split_whitespace().last())
.and_then(|hex| u8::from_str_radix(hex.get(0..2)?, 16).ok())
.is_some_and(|b| b & 1 == 1)
/// Whether the person turned storebound off in Windows' Startup apps (Settings / Task Manager), from the
/// HKCU\...\Explorer\StartupApproved\Run value named like the Run entry: its first byte is even when enabled (02, 06),
/// odd when disabled (03, 07). No value: not turned off. Pure.
pub fn startup_approved_off(value: &[u8]) -> bool {
value.first().is_some_and(|b| b & 1 == 1)
}
#[cfg(windows)]
fn startup_disabled_by_user() -> bool {
use std::os::windows::process::CommandExt;
const CREATE_NO_WINDOW: u32 = 0x0800_0000;
std::process::Command::new("reg")
.args(["query", r"HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run", "/v", "storebound"])
.creation_flags(CREATE_NO_WINDOW)
.output()
.map(|o| startup_approved_off(&String::from_utf8_lossy(&o.stdout)))
use winreg::{enums::HKEY_CURRENT_USER, RegKey};
RegKey::predef(HKEY_CURRENT_USER)
.open_subkey(r"Software\Microsoft\Windows\CurrentVersion\Explorer\StartupApproved\Run")
.and_then(|k| k.get_raw_value("storebound"))
.map(|v| startup_approved_off(&v.bytes))
.unwrap_or(false)
}