This commit is contained in:
Julian Freeman
2025-11-27 08:50:18 -04:00
parent 26d04daceb
commit 0ff1014e62
3 changed files with 32 additions and 19 deletions

11
src-tauri/Cargo.lock generated
View File

@@ -872,15 +872,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "encoding_rs_io"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cc3c5651fb62ab8aa3103998dade57efdd028544bd300516baa31840c252a83"
dependencies = [
"encoding_rs",
]
[[package]]
name = "endi"
version = "1.1.0"
@@ -3718,8 +3709,6 @@ version = "0.1.0"
dependencies = [
"chrono",
"csv",
"encoding_rs",
"encoding_rs_io",
"minidump",
"serde",
"serde_json",

View File

@@ -27,11 +27,7 @@ wmi = "0.13"
chrono = { version = "0.4", features = ["serde"] }
tokio = { version = "1", features = ["full"] }
minidump = "0.19"
# [新增] 用于解析 BlueScreenView 导出的 CSV
csv = "1.3"
# [新增] 用于处理可能的文件编码问题
encoding_rs = "0.8"
encoding_rs_io = "0.1"
[features]
# this feature is used for production builds or when `devPath` points to the filesystem

View File

@@ -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();