update event log
This commit is contained in:
@@ -1,3 +1,5 @@
|
|||||||
|
// src-tauri/src/main.rs
|
||||||
|
|
||||||
// 全局允许非标准命名风格 (因为 WMI 结构体必须匹配 Windows API 的命名)
|
// 全局允许非标准命名风格 (因为 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")]
|
||||||
@@ -24,15 +26,10 @@ struct SystemHealthReport {
|
|||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct HardwareSummary {
|
struct HardwareSummary {
|
||||||
cpu_name: String,
|
cpu_name: String,
|
||||||
|
|
||||||
// [新增] 1. 整机信息 (适合品牌机/笔记本)
|
|
||||||
sys_vendor: String,
|
sys_vendor: String,
|
||||||
sys_product: String,
|
sys_product: String,
|
||||||
|
|
||||||
// [新增] 2. 主板信息 (适合 DIY 组装机)
|
|
||||||
mobo_vendor: String,
|
mobo_vendor: String,
|
||||||
mobo_product: String,
|
mobo_product: String,
|
||||||
|
|
||||||
memory_total_gb: u64,
|
memory_total_gb: u64,
|
||||||
memory_used_gb: u64,
|
memory_used_gb: u64,
|
||||||
os_version: String,
|
os_version: String,
|
||||||
@@ -54,6 +51,7 @@ struct SystemEvent {
|
|||||||
time_generated: String,
|
time_generated: String,
|
||||||
event_id: u32,
|
event_id: u32,
|
||||||
source: String,
|
source: String,
|
||||||
|
message: String,
|
||||||
analysis_hint: String,
|
analysis_hint: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,6 +89,7 @@ struct Win32_NTLogEvent {
|
|||||||
TimeGenerated: String,
|
TimeGenerated: String,
|
||||||
EventCode: u32,
|
EventCode: u32,
|
||||||
SourceName: String,
|
SourceName: String,
|
||||||
|
Message: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug)]
|
#[derive(serde::Deserialize, Debug)]
|
||||||
@@ -111,14 +110,12 @@ struct Win32_BIOS {
|
|||||||
SMBIOSBIOSVersion: Option<String>,
|
SMBIOSBIOSVersion: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// 主板 WMI 结构 (DIY看这个)
|
|
||||||
#[derive(serde::Deserialize, Debug)]
|
#[derive(serde::Deserialize, Debug)]
|
||||||
struct Win32_BaseBoard {
|
struct Win32_BaseBoard {
|
||||||
Manufacturer: Option<String>,
|
Manufacturer: Option<String>,
|
||||||
Product: Option<String>,
|
Product: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// [新增] 整机 WMI 结构 (品牌机看这个)
|
|
||||||
#[derive(serde::Deserialize, Debug)]
|
#[derive(serde::Deserialize, Debug)]
|
||||||
struct Win32_ComputerSystem {
|
struct Win32_ComputerSystem {
|
||||||
Manufacturer: Option<String>,
|
Manufacturer: Option<String>,
|
||||||
@@ -173,20 +170,17 @@ async fn run_diagnosis() -> Result<SystemHealthReport, String> {
|
|||||||
let mut sys_product = "Unknown".to_string();
|
let mut sys_product = "Unknown".to_string();
|
||||||
|
|
||||||
if let Some(con) = &wmi_con {
|
if let Some(con) = &wmi_con {
|
||||||
// 获取 BIOS 版本
|
|
||||||
if let Ok(results) = con.raw_query::<Win32_BIOS>("SELECT SMBIOSBIOSVersion FROM Win32_BIOS") {
|
if let Ok(results) = con.raw_query::<Win32_BIOS>("SELECT SMBIOSBIOSVersion FROM Win32_BIOS") {
|
||||||
if let Some(bios) = results.first() {
|
if let Some(bios) = results.first() {
|
||||||
bios_ver = bios.SMBIOSBIOSVersion.clone().unwrap_or("Unknown".to_string());
|
bios_ver = bios.SMBIOSBIOSVersion.clone().unwrap_or("Unknown".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 获取主板信息 (BaseBoard)
|
|
||||||
if let Ok(results) = con.raw_query::<Win32_BaseBoard>("SELECT Manufacturer, Product FROM Win32_BaseBoard") {
|
if let Ok(results) = con.raw_query::<Win32_BaseBoard>("SELECT Manufacturer, Product FROM Win32_BaseBoard") {
|
||||||
if let Some(board) = results.first() {
|
if let Some(board) = results.first() {
|
||||||
mobo_vendor = board.Manufacturer.clone().unwrap_or("Unknown".to_string());
|
mobo_vendor = board.Manufacturer.clone().unwrap_or("Unknown".to_string());
|
||||||
mobo_product = board.Product.clone().unwrap_or("Unknown".to_string());
|
mobo_product = board.Product.clone().unwrap_or("Unknown".to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// [新增] 获取整机信息 (ComputerSystem)
|
|
||||||
if let Ok(results) = con.raw_query::<Win32_ComputerSystem>("SELECT Manufacturer, Model FROM Win32_ComputerSystem") {
|
if let Ok(results) = con.raw_query::<Win32_ComputerSystem>("SELECT Manufacturer, Model FROM Win32_ComputerSystem") {
|
||||||
if let Some(cs) = results.first() {
|
if let Some(cs) = results.first() {
|
||||||
sys_vendor = cs.Manufacturer.clone().unwrap_or("Unknown".to_string());
|
sys_vendor = cs.Manufacturer.clone().unwrap_or("Unknown".to_string());
|
||||||
@@ -218,7 +212,6 @@ async fn run_diagnosis() -> Result<SystemHealthReport, String> {
|
|||||||
cpu_name: cpu_brand,
|
cpu_name: cpu_brand,
|
||||||
mobo_vendor,
|
mobo_vendor,
|
||||||
mobo_product,
|
mobo_product,
|
||||||
// [新增] 填入整机数据
|
|
||||||
sys_vendor,
|
sys_vendor,
|
||||||
sys_product,
|
sys_product,
|
||||||
memory_total_gb: sys.total_memory() / 1024 / 1024 / 1024,
|
memory_total_gb: sys.total_memory() / 1024 / 1024 / 1024,
|
||||||
@@ -251,24 +244,40 @@ 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 {
|
||||||
let query = "SELECT TimeGenerated, EventCode, SourceName FROM Win32_NTLogEvent WHERE Logfile = 'System' AND (EventCode = 41 OR EventCode = 18 OR EventCode = 19)";
|
// 先按 ID 粗查
|
||||||
if let Ok(mut results) = con.raw_query::<Win32_NTLogEvent>(query) {
|
let query = "SELECT TimeGenerated, EventCode, SourceName, Message FROM Win32_NTLogEvent WHERE Logfile = 'System' AND (EventCode = 41 OR EventCode = 18 OR EventCode = 19)";
|
||||||
results.truncate(5);
|
if let Ok(results) = con.raw_query::<Win32_NTLogEvent>(query) {
|
||||||
|
// 不在这里 truncate,而是过滤后再截取,保证显示的是真问题
|
||||||
for event in results {
|
for event in results {
|
||||||
let hint = match event.EventCode {
|
let mut is_target_event = false;
|
||||||
41 => "系统意外断电 (电源/强关)",
|
let mut hint = String::new();
|
||||||
18 | 19 => "WHEA 硬件致命错误 (CPU/超频)",
|
|
||||||
_ => "系统关键错误",
|
// [修复逻辑] 必须同时匹配 ID 和 Source
|
||||||
};
|
if event.EventCode == 41 && event.SourceName == "Microsoft-Windows-Kernel-Power" {
|
||||||
events.push(SystemEvent {
|
is_target_event = true;
|
||||||
time_generated: format_wmi_time(&event.TimeGenerated),
|
hint = "系统意外断电 (电源/强关)".to_string();
|
||||||
event_id: event.EventCode,
|
} else if (event.EventCode == 18 || event.EventCode == 19) && event.SourceName == "Microsoft-Windows-WHEA-Logger" {
|
||||||
source: event.SourceName,
|
is_target_event = true;
|
||||||
analysis_hint: hint.to_string(),
|
hint = "WHEA 硬件致命错误 (CPU/超频/PCIe)".to_string();
|
||||||
});
|
}
|
||||||
|
|
||||||
|
if is_target_event {
|
||||||
|
events.push(SystemEvent {
|
||||||
|
time_generated: format_wmi_time(&event.TimeGenerated),
|
||||||
|
event_id: event.EventCode,
|
||||||
|
source: event.SourceName,
|
||||||
|
message: event.Message.unwrap_or("无详细信息".to_string()),
|
||||||
|
analysis_hint: hint,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 只需要最近的 5 条真实错误
|
||||||
|
if events.len() >= 5 {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/App.vue
12
src/App.vue
@@ -201,6 +201,8 @@
|
|||||||
<span class="event-time">{{ formatTime(evt.time_generated) }}</span>
|
<span class="event-time">{{ formatTime(evt.time_generated) }}</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="description highlight">{{ evt.analysis_hint }}</p>
|
<p class="description highlight">{{ evt.analysis_hint }}</p>
|
||||||
|
<!-- 新增:显示原始错误信息 -->
|
||||||
|
<p v-if="evt.message" class="description raw-message">{{ evt.message }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -632,6 +634,16 @@ h2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.description.highlight { color: #d35400; font-weight: 500; }
|
.description.highlight { color: #d35400; font-weight: 500; }
|
||||||
|
.description.raw-message {
|
||||||
|
margin-top: 5px;
|
||||||
|
font-size: 0.85rem;
|
||||||
|
color: #7f8c8d;
|
||||||
|
font-family: Consolas, Monaco, 'Courier New', monospace;
|
||||||
|
background: #f0f3f4;
|
||||||
|
padding: 5px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
/* 状态文本与徽章 */
|
/* 状态文本与徽章 */
|
||||||
.status-text { font-weight: 600; font-size: 0.9rem; }
|
.status-text { font-weight: 600; font-size: 0.9rem; }
|
||||||
|
|||||||
Reference in New Issue
Block a user