diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 2559ad6..43655ec 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -1,6 +1,6 @@ // src-tauri/src/main.rs -// 全局允许非标准命名风格 (因为 WMI 结构体必须匹配 Windows API 的命名) +// 全局允许非标准命名风格 #![allow(non_camel_case_types, non_snake_case)] #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] @@ -8,8 +8,8 @@ use serde::Serialize; use sysinfo::{System, Disks}; use wmi::{COMLibrary, WMIConnection}; use std::fs; -// 引入 chrono 用于时间格式化 -use chrono::{FixedOffset, Local, NaiveDate, TimeZone}; +// 引入 chrono 用于时间计算和格式化 +use chrono::{Duration, FixedOffset, Local, NaiveDate, TimeZone}; // --- 1. 数据结构 --- @@ -122,7 +122,16 @@ struct Win32_ComputerSystem { Model: Option, } -// --- 辅助函数:格式化 WMI 时间 --- +// --- 辅助函数:生成 WMI 查询用的时间字符串 --- +// WMI 要求的时间格式类似于: 20231125000000.000000+000 +fn get_wmi_query_time(days_ago: i64) -> String { + let target_date = Local::now() - Duration::days(days_ago); + // 这里我们只生成前半部分 YYYYMMDDHHMMSS,WMI 字符串比较支持这种前缀 + // 或者生成完整格式 .000000+000 (简化处理,假设本地时区) + target_date.format("%Y%m%d%H%M%S.000000+000").to_string() +} + +// --- 辅助函数:格式化显示用的时间 --- fn format_wmi_time(wmi_str: &str) -> String { if wmi_str.len() < 25 { return wmi_str.to_string(); @@ -157,8 +166,10 @@ fn format_wmi_time(wmi_str: &str) -> String { #[tauri::command] async fn run_diagnosis() -> Result { let report = tokio::task::spawn_blocking(|| { - let mut sys = System::new_all(); - sys.refresh_all(); + // 1. 高效初始化:只创建空实例,不扫描进程 + let mut sys = System::new(); + sys.refresh_memory(); + sys.refresh_cpu(); let wmi_con = WMIConnection::new(COMLibrary::new().unwrap()).ok(); @@ -244,18 +255,24 @@ async fn run_diagnosis() -> Result { } } - // 3. 关键日志 (严格模式 + 扩展) + // 3. 关键日志 (严格模式 + 时间优化 + 扩展) let mut events = Vec::new(); if let Some(con) = &wmi_con { - // [新增] 增加了 ID 7 (Disk), 1001 (BugCheck), 4101 (Display) - let query = "SELECT TimeGenerated, EventCode, SourceName, Message FROM Win32_NTLogEvent WHERE Logfile = 'System' AND (EventCode = 41 OR EventCode = 18 OR EventCode = 19 OR EventCode = 7 OR EventCode = 1001 OR EventCode = 4101)"; - if let Ok(results) = con.raw_query::(query) { - // 不在这里 truncate,而是过滤后再截取,保证显示的是真问题 + // [关键优化] 计算30天前的时间字符串 + let start_time_str = get_wmi_query_time(30); + + // [关键优化] SQL 中加入 TimeGenerated >= '...' 过滤,大幅减少扫描量 + let query = format!( + "SELECT TimeGenerated, EventCode, SourceName, Message FROM Win32_NTLogEvent WHERE Logfile = 'System' AND TimeGenerated >= '{}' AND (EventCode = 41 OR EventCode = 18 OR EventCode = 19 OR EventCode = 7 OR EventCode = 1001 OR EventCode = 4101)", + start_time_str + ); + + if let Ok(results) = con.raw_query::(&query) { for event in results { let mut is_target_event = false; let mut hint = String::new(); - // [修复逻辑] 必须同时匹配 ID 和 Source + // 严格来源校验 if event.EventCode == 41 && event.SourceName == "Microsoft-Windows-Kernel-Power" { is_target_event = true; hint = "系统意外断电 (电源/强关)".to_string(); @@ -263,15 +280,12 @@ async fn run_diagnosis() -> Result { is_target_event = true; hint = "WHEA 硬件致命错误 (CPU/超频/PCIe)".to_string(); } else if event.EventCode == 7 && (event.SourceName == "Disk" || event.SourceName == "disk") { - // [新增] 磁盘坏块检测 is_target_event = true; hint = "硬盘出现坏道 (Disk Bad Block)".to_string(); } else if event.EventCode == 1001 && event.SourceName == "BugCheck" { - // [新增] 蓝屏记录 is_target_event = true; hint = "系统发生蓝屏死机 (BSOD)".to_string(); } else if event.EventCode == 4101 && event.SourceName == "Display" { - // [新增] 显卡驱动重置 is_target_event = true; hint = "显卡驱动停止响应并已恢复 (TDR)".to_string(); } @@ -286,8 +300,8 @@ async fn run_diagnosis() -> Result { }); } - // 只需要最近的 5 条真实错误 - if events.len() >= 5 { + // 显示最近 10 条(因为加了时间范围,可以多显示一点) + if events.len() >= 10 { break; } }