improve scan speed

This commit is contained in:
Julian Freeman
2025-11-25 23:31:07 -04:00
parent 221394670d
commit d18f36bc13

View File

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