split event log
This commit is contained in:
@@ -9,7 +9,6 @@ use sysinfo::{System, Disks};
|
||||
use wmi::{COMLibrary, WMIConnection};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
// [修复] 移除了未使用的 Write
|
||||
use std::io::Read;
|
||||
use std::process::Command;
|
||||
use tauri::Emitter;
|
||||
@@ -232,16 +231,15 @@ where T: Deref<Target = [u8]>
|
||||
})
|
||||
}
|
||||
|
||||
// [修复] BlueScreenView 外部调用分析 (适配新的命令行格式和 CSV 列)
|
||||
// BlueScreenView 外部调用分析
|
||||
fn analyze_with_bluescreenview(dump_path: &Path) -> Result<BsodAnalysisReport, String> {
|
||||
let bsv_exe = "BlueScreenView.exe";
|
||||
|
||||
let mut temp_csv_path = std::env::temp_dir();
|
||||
temp_csv_path.push(format!("bsod_report_{}.csv", chrono::Utc::now().timestamp_millis()));
|
||||
|
||||
// [修改] 命令行格式: BlueScreenView.exe <DumpFile> /scomma <OutFile>
|
||||
let status = Command::new(bsv_exe)
|
||||
.arg(dump_path.to_string_lossy().to_string()) // 直接传文件路径
|
||||
.arg(dump_path.to_string_lossy().to_string())
|
||||
.arg("/scomma")
|
||||
.arg(temp_csv_path.to_string_lossy().to_string())
|
||||
.status();
|
||||
@@ -250,35 +248,26 @@ fn analyze_with_bluescreenview(dump_path: &Path) -> Result<BsodAnalysisReport, S
|
||||
return Err("未找到 BlueScreenView.exe,无法分析内核转储文件。请将 BlueScreenView.exe 放入程序目录。".to_string());
|
||||
}
|
||||
|
||||
// 读取字节并转为 String (lossy 模式,防止 GBK/ANSI 乱码导致 panic)
|
||||
let content_bytes = fs::read(&temp_csv_path).map_err(|_| "BlueScreenView 分析未生成有效数据。".to_string())?;
|
||||
let _ = fs::remove_file(temp_csv_path);
|
||||
let content = String::from_utf8_lossy(&content_bytes);
|
||||
|
||||
// 使用 csv crate 解析
|
||||
let mut rdr = csv::ReaderBuilder::new()
|
||||
.has_headers(false) // 命令行模式导出的 CSV 没有 Header,第一行就是数据
|
||||
.has_headers(false)
|
||||
.from_reader(content.as_bytes());
|
||||
|
||||
for result in rdr.records() {
|
||||
if let Ok(record) = result {
|
||||
// BlueScreenView CSV 格式 (基于上传的文件):
|
||||
// Index 0: Dump File (112525-7375-01.dmp)
|
||||
// Index 2: Bug Check String (MEMORY_MANAGEMENT)
|
||||
// Index 3: Bug Check Code (0x0000001a)
|
||||
// Index 8: Caused By Driver (ntoskrnl.exe)
|
||||
// Index 15: Crash Address (ntoskrnl.exe+41e230)
|
||||
|
||||
if record.len() > 15 {
|
||||
// 第一行就是数据,不需要跳过 Header
|
||||
if &record[0] == "Dump File" { continue; }
|
||||
|
||||
let bug_check_string = &record[2];
|
||||
let bug_check_code = &record[3];
|
||||
let caused_by_driver = &record[8];
|
||||
let crash_addr = &record[15];
|
||||
let crash_addr = if record.len() > 15 { &record[15] } else { "N/A" };
|
||||
|
||||
let (human, recommend) = translate_bugcheck_str(bug_check_code);
|
||||
|
||||
// 优先使用 BlueScreenView 识别出的 Bug Check String
|
||||
let final_reason = if !bug_check_string.is_empty() { bug_check_string.to_string() } else { human };
|
||||
|
||||
return Ok(BsodAnalysisReport {
|
||||
@@ -375,7 +364,7 @@ async fn analyze_minidump(filepath: String) -> Result<BsodAnalysisReport, String
|
||||
}
|
||||
}
|
||||
|
||||
// [修复] 命令:分析二进制内容的 Minidump
|
||||
// 命令:分析二进制内容的 Minidump
|
||||
#[tauri::command]
|
||||
async fn analyze_minidump_bytes(file_content: Vec<u8>) -> Result<BsodAnalysisReport, String> {
|
||||
if file_content.is_empty() {
|
||||
@@ -386,7 +375,6 @@ async fn analyze_minidump_bytes(file_content: Vec<u8>) -> Result<BsodAnalysisRep
|
||||
|
||||
match dump_type {
|
||||
DumpType::Minidump => {
|
||||
// [修复] 修复 Error 类型转换
|
||||
let native_result = Minidump::read(file_content.clone())
|
||||
.map_err(|e| e.to_string())
|
||||
.and_then(|dump| analyze_dump_data_native(dump));
|
||||
@@ -394,7 +382,6 @@ async fn analyze_minidump_bytes(file_content: Vec<u8>) -> Result<BsodAnalysisRep
|
||||
if let Ok(report) = native_result {
|
||||
return Ok(report);
|
||||
}
|
||||
// 失败回退到 BSV
|
||||
},
|
||||
DumpType::KernelDump => {
|
||||
// 直接回退
|
||||
@@ -402,7 +389,6 @@ async fn analyze_minidump_bytes(file_content: Vec<u8>) -> Result<BsodAnalysisRep
|
||||
DumpType::Unknown => return Err("无效的文件签名。请确认这是 .dmp 文件。".to_string())
|
||||
}
|
||||
|
||||
// --- 回退流程:写入临时文件调用 BlueScreenView ---
|
||||
let mut temp_dump_path = std::env::temp_dir();
|
||||
temp_dump_path.push(format!("temp_dump_{}.dmp", chrono::Utc::now().timestamp_millis()));
|
||||
|
||||
@@ -582,7 +568,7 @@ async fn run_diagnosis(window: tauri::Window) -> Result<(), String> {
|
||||
analysis_hint: hint,
|
||||
});
|
||||
}
|
||||
if events.len() >= 10 { break; }
|
||||
// [修改] 移除了数量限制,让它获取所有符合条件的日志
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user