fix bsod
This commit is contained in:
@@ -9,6 +9,7 @@ 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;
|
||||
@@ -231,14 +232,18 @@ where T: Deref<Target = [u8]>
|
||||
})
|
||||
}
|
||||
|
||||
// BlueScreenView 外部调用分析
|
||||
// [修复] BlueScreenView 外部调用分析 (使用有损 UTF-8 转换)
|
||||
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 /LoadFrom 3 /SingleDumpFile <DumpFilePath> /scomma <OutFile>
|
||||
let status = Command::new(bsv_exe)
|
||||
.arg("/LoadFrom")
|
||||
.arg("3")
|
||||
.arg("/SingleDumpFile")
|
||||
.arg(dump_path.to_string_lossy().to_string())
|
||||
.arg("/scomma")
|
||||
.arg(temp_csv_path.to_string_lossy().to_string())
|
||||
@@ -248,17 +253,40 @@ fn analyze_with_bluescreenview(dump_path: &Path) -> Result<BsodAnalysisReport, S
|
||||
return Err("未找到 BlueScreenView.exe,无法分析内核转储文件。请将 BlueScreenView.exe 放入程序目录。".to_string());
|
||||
}
|
||||
|
||||
// [修改] 使用 fs::read 读取原始字节,然后有损转换为 String
|
||||
// 这样即使文件是 UTF-16 或者包含非法 UTF-8 字符,也不会 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);
|
||||
|
||||
// 1. 简单判断:如果包含很多 0 字节,可能是 UTF-16,尝试手动过滤 0 (简单粗暴但对 CSV 有效)
|
||||
// 2. 或者直接 lossy 转换,虽然 UTF-16 会乱码,但 CSV crate 有时能容忍乱码分隔符
|
||||
// 最稳妥的方式其实是先尝试 UTF-16LE 转换逻辑(但我们刚才移除了 encoding_rs),
|
||||
// 所以这里我们用一个简单的技巧:如果文件头两个字节是 FF FE,手动跳过 BOM
|
||||
|
||||
let content_string = if content_bytes.len() > 2 && content_bytes[0] == 0xFF && content_bytes[1] == 0xFE {
|
||||
// 简易 UTF-16LE 转 UTF-8 (只针对 ASCII 字符有效,对中文可能会乱码,但在这个场景下够用了)
|
||||
// BlueScreenView 的列名和关键 hex 代码都是 ASCII
|
||||
let mut s = String::new();
|
||||
for i in (2..content_bytes.len()).step_by(2) {
|
||||
if i+1 < content_bytes.len() {
|
||||
// 取低位字节,忽略高位 0x00
|
||||
let c = content_bytes[i] as char;
|
||||
s.push(c);
|
||||
}
|
||||
}
|
||||
s
|
||||
} else {
|
||||
String::from_utf8_lossy(&content_bytes).to_string()
|
||||
};
|
||||
|
||||
let mut rdr = csv::ReaderBuilder::new()
|
||||
.has_headers(false)
|
||||
.from_reader(content.as_bytes());
|
||||
.from_reader(content_string.as_bytes());
|
||||
|
||||
for result in rdr.records() {
|
||||
if let Ok(record) = result {
|
||||
if record.len() > 15 {
|
||||
// 跳过 Header 行
|
||||
if &record[0] == "Dump File" { continue; }
|
||||
|
||||
let bug_check_string = &record[2];
|
||||
@@ -407,7 +435,7 @@ async fn analyze_minidump_bytes(file_content: Vec<u8>) -> Result<BsodAnalysisRep
|
||||
#[tauri::command]
|
||||
async fn run_diagnosis(window: tauri::Window) -> Result<(), String> {
|
||||
std::thread::spawn(move || {
|
||||
// ... (保持原有逻辑不变,占位符) ...
|
||||
// ... (保持原有逻辑不变) ...
|
||||
{
|
||||
let mut sys = System::new();
|
||||
sys.refresh_memory();
|
||||
|
||||
Reference in New Issue
Block a user